I'm having a tough time figuring out how to run NodeJS from Python. I have no problems running ShellScript from Python and NodeJS from ShellScript, but can't seem to get NodeJS from Python, I just get the following output:
b"
These are the simplified version of my scripts.
NodeJS I am trying to run from within Python.
#!/usr/bin/env node
console.log("Hello " + process.argv[2]);
And here is the Python, using Python3.
from datetime import datetime
import json
import os
import re
import sys
import subprocess
if __name__ == '__main__':
p = subprocess.Popen(['/Users/Brett/scripts/hello.js', 'Brett'], stdout=subprocess.PIPE)
out = p.stdout.read()
print(out)
Thanks for the help! Much appreciated.
EDITS: I have no issue executing the following from the commandline, as 'hello.js' is executable:
hello.js 'Brett'
shell=true does not fix it.
Additionally, I am on macOS Catalina 10.15.5 and therefore my shell is zsh.
If I add node to the front of the command, I get no such file or directory for node, I tried it as follows:
p = subprocess.Popen(['/Users/Brett/scripts/hello.js', 'Brett'], stdout=subprocess.PIPE)
3 Answers 3
Thanks everyone for the responses. All were super helpful. Especially @max-stanley and @jared-smith.
The following ended up working for me:
p = subprocess.Popen(['/usr/local/bin/node', '/Users/Brett/scripts/hello.js', 'Brett'], stdout=subprocess.PIPE)
out = p.stdout.read()
print(out)
Not sure why it doesn't work with the shebang in the executable js file but I am not committed to it, so I will just take the working solution and move on. ;-)
Cheers!
Comments
Okay after doing some testing based on the comments by Max Stanley:
There is an inconsistency between Linux and MacOS here about the population of the argv array. On Mac you will want the second index (1) and on Linux you will want the third (2).
I recommend using a command-line argument parser like command-line-args which should paper over the platform differences.
In the meantime you can specify node in the python subprocess call Popen(["node", "/Users/Brett/scripts/hello.js", "Brett"]) which has the same behavior on both.
5 Comments
p = subprocess.Popen(['node', '/Users/Brett/scripts/hello.js', 'Brett'], stdout=subprocess.PIPE)'node' to the path where nodejs is installed on your system.shutil.which() to find node.Having tested this on my system, it looks as though you need to either make the hello.js file executable chmod +x ./hello.js or you need to add 'node' to the beginning of the Popen argument list as @Jared had said.
node hello.js Brettthen it would be the third element in argv, but since you used the hashbang and are calling it like a script it would be the second (at index 1) argument. You can see how this fails by calling it without python directly in the shell:cd /Users/Brett/scripts; ./hello.js Brett. Either specify node in the python subprocess callPopen(["node", "/Users/Brett/scripts/hello.js", "Brett"])or change the index into sys.argv to 1.bash $ node ./hello.js Brett Hello Brett [ '/usr/bin/node', '/tmp/so/1/hello.js', 'Brett' ] $ chmod +x hello.js $ ./hello.js Brett Hello Brett [ '/usr/bin/node', '/tmp/so/1/hello.js', 'Brett' ]