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" bob@123.1.2.3 /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" bob@123.1.2.3 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
Ricardo
  • 3,696
  • 5
  • 36
  • 50

2 Answers2

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" bob@123.1.2.3 'bash -ic "/path/to/myscript arg1"'
  • 1
    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`... – Michał Karpacki Mar 26 '19 at 19:40
  • 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 Mar 26 '19 at 23:16
  • @Ricardo, perhaps there is a solution... can you do the following: `ssh -t 'bash -ic '"'"'echo $PATH'"'"''`? I suppose the output will be somewhat different to `ssh -t 'echo $PATH'`... it's probably a matter where you actually set the path. – Michał Karpacki Mar 27 '19 at 14:16
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" bob@123.1.2.3 "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?
Ricardo
  • 3,696
  • 5
  • 36
  • 50
  • It also worked w/o adding quotes: `ssh -o "PasswordAuthentication no" bob@123.1.2.3 export PATH=$PATH;/path/to/myscript arg1` – Ricardo Mar 27 '19 at 00:53