Execute 'mv' command common in Bash, Zsh, PowerShell, CMD - node.js

Im trying to create CLI using node.js and I have some tasks where I need to move a folder from one place to another. So to achieve this I used node.js's child_process. Like this:
const { exec } = require("child_process");
function moveFolder(folder,destination){
exec(
`mv ${folder} ${destination}`,
(error, stdout, stderr) => {
if (error) {
console.log("Move error");
}
console.log("Move success");
}
);
}
This piece of code works when I execute this with bash terminal (git-bash or in Linux). But when I execute it using CMD or PowerShell it throws an error
'mv' is not recognized as an internal or external command.
I know PowerShell and CMD have a command called move to achieve this, and that's why it is throwing the error. But is there a way (library or some other method) to execute these types of commands in all environments? (in Windows (CMD, PowerShell), Linux (bash, zsh), Mac OS (zsh)). How can I achieve this?. Can we detect the shell type and execute different commands?

Related

Calling processing-java from nodejs on Windows 10

I am having some problems to execute the processing-java on windows from nodejs. When I use the following
processing-java --sketch=$pwd/sketch/ --run
in the console it works fine and the sketch is executed, window opens and the result is a file written to a directory where I need it.
But when I use the same as a string in the node file to execute it, it does not open a window and no file has been written, but the callback function processOutput is executed, hence the somehow the execution happened.
I added
const exec = require('child_process').exec;
to the js file which is used for executing child processes in node.
$pwd is the PowerShell equivalent to pwd on MacOS.
exec should execute the shell command and call the callback function. The callback function is executed, but not the sketch.
const cmd = 'processing-java --sketch=$pwd/sketch/ --run';
exec(cmd, processOutput);
What am I missing? Any help appreceated.
Many thanks, C.
child_process.exec() does not execute in a powershell but in a CMD terminal. Thus you can't use powershell variables like $pwd. You could try using %CD% instead
const cmd = 'processing-java --sketch=%CD%/sketch/ --run';
exec(cmd, processOutput);

Cannot capture stdout output of child process of batch script

Using Node.js, I'm writing a Windows Batch script which calls some external programs. I want to execute this script and capture its output (and that of its children) to be able to display it inside an HTML container (I'm writing an Electron application). On Linux, I generate a Bash script that runs perfectly fine and whose output I can capture correctly. However, once the Windows Batch script spawns its child processes, I'm unable to capture their stdout and stderr; the only output child.stdout.on ("data", () => { /* ... */ }); catches is that of the Batch script itself.
I have tried various variants of how the Batch script calls the external programs, so far, neither has had the desired effect: all of them opened a new cmd.exe window. Using the advice from start /?, I am currently calling the programs as follows:
start /b /wait PROGRAM ARGUMENTS
(Where PROGRAM for example is pdflatex.exe.) By appending 2>&1 I was able to suppress new cmd.exe windows by running the batch script out of a cmd.exe window, but not by calling it from Node.js. I'm using the following code to call the Batch script:
const { spawn } = require ("child_process");
var child = spawn (
"call",
[ "path/to/batch.bat" ],
{
detached: true,
shell: true
}
);
Directly calling the Batch script by using the path to it as the command argument of spawn (); did not have the desired effect either.
Another method of invoking the Batch script and external programs I have tried but which did not have the desired result either, was to directly call the external programs from the Batch script like
C:\Full\Path\To\pdflatex.exe -halt-on-error -output-format=pdf file.tex
and using the Batch script's full path as the command argument to spawn (); like so:
const { spawn } = require ("child_process");
var child = spawn (
"C:/Full/Path/To/Batch.bat",
[ ],
{
detached: true,
shell: true
}
);
This did, like all other methods, capture the output of the cmd.exe process interpreting the script but opened a new cmd.exe window for all external programs called by the Batch script. The only other contents of the Batch script are along the lines of:
#echo off
REM Cd into the desired working directory
CD /D "C:\Path\To\Cwd"
REM Execute external programs like pdflatex:
C:\Full\Path\To\pdflatex.exe -halt-on-error -output-format=pdf file.tex
Nothing in the Batch script should actually interfere with how the commands are handled, but obviously this is not the case.
I am fine with modifying the call to spawn (); for Windows only; however, I must run the external programs using a Batch script and not using spawn (); directly because there is a requirement for backward compatibility I must meet.
So, after all, how would I be able to capture grandchild processes' stdout using a Batch script in Node.js?

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.

Simple bash commands fails, cannot execute binary file

I try to execute some simple bash in node bu get an error:
/usr/bin/file: /usr/bin/file: cannot execute binary file
'use strict';
var spawn = require('child_process').spawn;
var process = spawn('bash', ['file']);
process.stdout.on('data', function(data){
console.log(data.toString());
});
process.stderr.on('data', function(data){
console.log(data.toString());
});
I even gave the script chmod+x and i run it with node script.js
Any ideas?
It looks like when you're spawning the child process, you're actually trying to run the "file" command, not a shell script, so bash is barking at you.
It would be equivalent to typing this on the command line: "bash file".
You'll want to write a shell script and pass that as the parameter to the bash process.
So, write a script called "do_something.sh" and then run your code with ['do_something.sh'] as the parameter to bash rather than ['file']:
var process = spawn('bash', ['do_something.sh']);

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