Launch node script from bash script - linux

I've my program in bash and I want to launch a node program to get the string that it return, like in this way:
#!/bin/bash
mystring=$( node getString.js)
mplayer $mystring
Googling I found that I should inlcude
#!/usr/bin/env node
But I need to use string to give it to mplayer.. any ideas?
Solution
As Zac suggesting (and thanks to this link) I solved my problem in this way:
script.sh
#!/bin/bash
mplayer ${1}
script.js
/* do whatever you need */
var output="string"
var sys = require('sys');
var exec = require('child_process').exec;
function puts(error, stdout, stderr) { sys.puts(stdout); }
exec("./script.sh " + output, puts);

Consider simply writing an executable Node script (with the #!/bin/env node line), and, instead of using Bash, just use Node to run the external UNIX command. You can use the child_process module for this, as illustrated in this example. This question is also helpful when debugging shell-style subcommands in Node scripts.
If your example really is all you need to do in Bash, this should be sufficient. The #!/bin/env node line allows your script, once marked as executable, to run as its own program, without having to be invoked with node.

Related

Expect command does not see stdout when executing with nodejs?

I wrote a bash file with expect command, expecting some output and do actions based on that it works when I execute it in the terminal but when I execute it using exec in nodejs it does not work. I think the output of commands I run in bash file cannot be seen by expect
I usually use, shelljs Package, for executing commands or shell scripts via nodejs.
const shell = require('shelljs')
shell.exec('./path_to_your_file')

Can I access CLI programs from within Node's child_process?

I’ve written a node script that cd’s into multiple directories in sequence and executes bash commands in order to deploy the contents of the repos to my development environment.
Native bash commands work fine, like cd, ls, but it looks like the subshell or child process (or whatever the proper term is, I don’t understand the inner workings of Bash) that’s opened by node doesn’t have anything available to my normal prompt.
E.g.
the custom bash toolset that’s available globally
nvm (is this even possible, to run a different version of node within a node subshell?)
gulp breaks because it doesn't have the necessary node version installed.
Is it possible to access these programs/commands from the node subshell? I’m using the child_process node module.
const { exec } = require('child_process');
function command (command) {
exec (command, (err, stdout, stderr) => {
if (err) {
error(err);
} else {
message(`stdout: ${stdout}`);
message(`stderr: ${stderr}`);
}
});
}
Used as in:
command('nvm use 6');
command('gulp build');
command('pde deploy');
The child process is not run as bash. child_process spawns the executable using the regular sh shell.
If you need the commands to run within bash, the command line you run needs to be wrapped in bash -c. For example:
command('bash -c "my command here"');
Also, each command you run is a sub-process, which does not affect the parent process, nor any subsequent sub processes. Thus, a shell built-in like cd will only change the directory for that sub-process, which immediately goes away. You will see this if you run:
command('cd /');
command('ls');
The ls command will show the current working directory, not the root directory.
If you run your command with bash -c and the $PATH and other environment variables still aren't set up the way you need them, you need to debug your shell start-up scripts. Perhaps there's a difference between interactive shells (.bash_profile) and all shells (.bashrc).
Note that fully non-interactive shells may need to explicitly have the start-up script you want to run specified.

Conditionals when initialising node.js scripts

I have a node.js executable script which usually starts with:
#!/usr/bin/env node
var ...
In order to use a command line argument --use_strict on the node.js binary, I'd need to change this to
#!/usr/bin/env node --use_strict
which could possibly screw up for other people.
Is there a way to check if --use_strict has been provided when calling the script and then pass it to the node executable?
something like
./myscript --use_strict
---
if --use_strict
#!/usr/bin/env node --use_strict
else
#!/usr/bin/env node
#!/usr/bin/env node will instruct the operating system to call the command after the #! ("shebang") on the file. If your script is in the file your-node-script, the OS basically runs this:
/usr/bin/env node your-node-script
The env command will search for the first argument in your environment and execute it with the remaining arguments. If your node executable is in /usr/bin/node, on your system it will call:
/usr/bin/node your-node-script
To solve your problem, you just write a wrapper script which does the same to call your node script:
#!/bin/bash
/usr/bin/env node --use-strict your-node-script "$#"
Or:
#!/bin/bash
/usr/bin/node --use-strict your-node-script "$#"
(Which only works on systems where node acrually is in /usr/bin.
Edit: Parameters are now forwarded (thanks Etan Reisner).

bash: terminal: command not found

I am trying to write a Node.js script that will start a Node.js server in a new process, in a new command window.
I believe I am close. I have this:
var n = cp.spawn('sh', [ 'start-server.sh' ]);
the contents of start-server.sh are like so
#!/usr/bin/env bash
node bin/www
this starts the server successfully, but it doesn't open a new terminal window, so I can't see any of the stdio of the spawned process.
So I am thinking that I should open a new terminal window in the bash script and then run the node command, so then the bash script contents would become
#!/usr/bin/env bash
terminal -e "node bin/www"
the problem is that "terminal" is not recognized at the command line. Why is that? I believe the "terminal" command should default to whatever program is being used as your default terminal application.
Please advise if this is the best way to do this and why "terminal" might not be recognized at the command line in OSX, thanks!
this is what is in my path
echo $PATH
/Users/amills001c/.rvm/gems/ruby-2.2.1/bin:/Users/amills001c/.rvm/gems/ruby-2.2.1#global/bin:/Users/amills001c/.rvm/rubies/ruby-2.2.1/bin:/Users/amills001c/google_app_engine_stuff/google-cloud-sdk/bin:/usr/local/bin:/usr/local/bin/meteor:/usr/local/redis/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/usr/local/git/bin:/Users/amills001c/golang/bin:/Users/amills001c/apache-maven-3.3.3/bin:/Users/amills001c/.rvm/bin
In OS X you would normally run the command like so:
open -a Terminal.app /path/to/script.sh
Which would open a new terminal window and execute your script.
Check the real name of the "terminal" command in your system, to check it, for example, in Ubuntu do "/usr/bin/env | grep terminal", in my case is "gnome-terminal", then use "gnome-terminal -e XXX" should work. Hope it helps J.
What worked for me was this:
var cp = require('child_process');
cp.spawn('sh', [ 'start-server.sh' ], {
detached: true,
env: {
NODE_ENV: process.env.NODE_ENV
}
});
#!/usr/bin/env bash (start-server.sh)
open "./run-node.sh"
#!/usr/bin/env bash (run-node.sh)
node ./bin/www.js
the open command will open the .sh file with the default app, which happens to be iterm2 for me, not terminal.app
the next problem I have is I have to pass paths as arguments to .sh files and I don't know how to do that yet

Using node.js and coffeescript for executing Ubuntu commands

I am using child_process.exec to execute Ubuntu commands with node.js in coffeescript. When I execute the following commands:
list = child_process.exec("ls")
print list
It prints this:
[Object Object]
Why isn't a proper output of ls command printed? What should I do to get a proper output for commands?
You're attempting to run an asynchronous function synchronously. The correct way to do this is:
var exec = require('child_process').exec;
exec('ls', function (error, stdout, stderr) {
console.log(stdout);
});
Source: https://nodejs.org/api/child_process.html#child_process_child_process_exec_command_options_callback
If you really wish to execute a command synchronously, you can use execSync. However, I'd advise against that, since it blocks your node code from doing anything until the process finishes.
ExecSync: https://nodejs.org/api/child_process.html#child_process_child_process_execsync_command_options
Found it!
Can be accessed using ->
print list.main.<attribute_name>

Resources