2

I want to remotely run a node.js script containing a shebang line through ssh, similarly as when running it locally.

myscript file:

#!/usr/bin/env node
var param  = process.argv[2] || 'help';
//... other js code

When running locally on each host – e.g. myscript arg1 – it runs successfully. When running remotely on a "sister" node in a cluster (containing the same file and directory structure, including nodeand myscript):

ssh -o "PasswordAuthentication no" [email protected] /path/to/myscript arg1

I get /usr/bin/env: ‘node’: No such file or directory error.

Am I missing a ssh param / option?


Mode details: If I run

ssh -o "PasswordAuthentication no" [email protected] echo "hello"

It also works fine. Forgive me it this is obvious to you, I'm not an advanced Linux user, the ssh manual seemed a little bit overwhelming and tried a couple answers found here with no success:

  1. What exactly does "/usr/bin/env node" do at the beginning of node files?
  2. Run scripts remotely via SSH
  3. how to run a script file remotely using ssh
4
  • Are you positive that node is installed the same on all nodes in the cluster? Commented Mar 26, 2019 at 18:53
  • I get that message when node is not installed or the path to node is wrong Commented Mar 26, 2019 at 18:58
  • Please check if this will run ssh -o "PasswordAuthentication no" [email protected] bash -c "/path/to/myscript arg1" Commented Mar 26, 2019 at 19:20
  • Question edited. Yes, node and myscript are installed in the same location; and no, bash -c "..." didn't get a different result. Commented Mar 26, 2019 at 23:00

2 Answers 2

1

If the node executable isn't already in your PATH environment variable at login, you could provide the full path to it in the shebang line of your script:

#!/usr/bin/env /full/path/to/node

As others have commented, you would have to update your script if the path to node ever changes. This is not ideal. Alternatively, you could force ssh to create a pseudo-terminal session by specifying the -t flag and run your script in an interactive bash shell:

ssh -t -o "PasswordAuthentication no" [email protected] 'bash -ic "/path/to/myscript arg1"'
Sign up to request clarification or add additional context in comments.

3 Comments

Hi Sebastian - I think this may be a working solution, but note that it's not an elegant solution - especially if you choose to use different versions of node etc. Hardcoding the full path to node could potentially affect the work of version managers like nvm...
Both local and remote hosts' PATH properly point to node and myscript locations. However, your suggestion worked after also adding quotes to "/path/to/myscript arg1". Is there a way, then, to make sure path is loaded by ssh, instead of hardcoding the /full/path/to/node onto myscript? This could cause a regression in case node's location is changed in the future...
@Ricardo, perhaps there is a solution... can you do the following: ssh <opts> -t 'bash -ic '"'"'echo $PATH'"'"''? I suppose the output will be somewhat different to ssh <opts> -t 'echo $PATH'... it's probably a matter where you actually set the path.
0

Sebastian's answer inspired me to find a solution that doesn't hardcode the full path to node on the script. Basically, I make sure the remote PATH is available before running the command:

ssh -o "PasswordAuthentication no" [email protected] "export PATH=$PATH;/path/to/myscript arg1"

But this only worked for me because both local and remote servers have the same PATH value, since the local PATH is being set onto the remote session.


Here there may be some ways to explore other solutions if your case is not like mine:

  1. How do I set $PATH such that `ssh user@host command` works?
  2. How to set PATH when running a ssh command?

1 Comment

It also worked w/o adding quotes: ssh -o "PasswordAuthentication no" [email protected] export PATH=$PATH;/path/to/myscript arg1

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.