I'm trying to download a lot of files using nodejs and the exec command, simplified like this:
var cmd = 'wget -O output.csv URL';
var child = exec(cmd, function(err) {
console.log('DONE');
});
However, the callback is triggered before the file was actually downloaded through wget, leading to a file that contains garbage like '��0O�6D�1n�]v�����#�'. Shouldn't the callback be triggered once wget is done? When running the same command on the command line it takes rougly 5 seconds, since the file has several MB.
Btw: I'm not using the request module since it's slower and I ran into emitter listener issues (EventEmitter memory leak detected. 11 listeners added).
Thanks!
This will involve some debugging.
Can you please try running your script as:
var cmd = 'wget -O output.csv URL';
var child = exec(
cmd,
function (error, stdout, stderr) {
console.log('stdout: ' + stdout);
console.log('stderr: ' + stderr);
if (error !== null) {
console.log('exec error: ' + error);
}
}
);
It would be interesting to see what stdout and stderr say.
Right, you provided me your stderr which said:
http://productdata.zanox.com/exportservice/v1/rest/22791753C32335607.csv?ticket=BC4B91472561713FD43BA766542E9240AFDD01B95B123E40B2C0375E3A68C142
This URL the command line gets is missing everything after the ampersand (& character). This indicates a problem with escaping.
To get around this try replacing \& with \\\&.
Related
I am trying to run a powershell command through a nodejs script. I have found the following two articles which have shown me something similar to what I am trying to acheive:
Execute Windows Commands with Nodejs
Execute powershell script from nodejs
On a button click event, I am trying to list the usb devices currently attached to the system along with its Drive Letter (C, D, E etc). If I run the command in the powershell on its own, it works (I am unable to get it to display the drive letter though). However, if I run it as part of my script it does not work. Below is my code:
if (process.platform === 'win32' || process.platform === 'win64') {
exec("powershell.exe",["GET-WMIOBJECT win32_diskdrive | Where { $_.InterfaceType –eq 'USB' }"], function (err, stdout, stderr) {
console.log(err);
console.log(stdout);
console.log(stderr);
});
}
What am I doing wrong?
You can use Node-PowerShell.
Node-PowerShell taking advantage of two of the simplest, effective and easy tools that exist in the today technology world. On the one hand, NodeJS which made a revolution in the world of javascript, and on the other hand, PowerShell which recently came out with an initial open-source, cross-platform version, and by connecting them together, gives you the power to create any solution you were asked to, no matter if you are a programmer, an IT or a DevOps guy.
Another way...
exec('command here', {'shell':'powershell.exe'}, (error, stdout, stderr)=> {
// do whatever with stdout
})
I believe you shold pass the code with -command before it. Default PowerShell syntax is: powershell.exe -command "get-wmiobject ...".
Something like this:
exec("powershell.exe",["-command \"Get-WmiObject -Class win32_diskdrive | Where { $_.InterfaceType -eq 'USB' }\""], function (err, stdout, stderr) {
console.log(err);
console.log(stdout);
console.log(stderr);
});
You'll want to request child_process with..
var exec = require("child_process").exec;
Then you'll want to call exec() to execute a child process, followed by the commands you want the child process to execute, you'll need to do this with a callback function as well as seen in the snippet below, you need this to catch errors in case something goes wrong and you need to fix it.
exec('CommandHere', {'shell':'powershell.exe'}, (error, stderr, stdout) => {
if (error !== null) {
// Do something
}
});
Here's an example using Powershell's set-location and gci commands to search recursively for a file within a specified directory and return it's relative path for Windows...
var exec = require("child_process").exec;
var folder = "C:\\Users\\winUser\\just\\some\\folder\\location";
var file = "test.txt";
exec('set-location ' + '"' + folder + '"' +
';' + ' gci -path ' + '"' + folder + '"' +
' -recurse -filter ' + '"' + file + '"' +
' -file | resolve-path relative',
{'shell':'powershell.exe'}, (error, stderr, stdout) => {
var filePath = stdout.substring(stdout.indexOf(".\\") + 2).trim("\n");
if (error !== null) {
console.log("Cannot locate the given file \n");
console.log(error);
}
console.log("File located! \n Path: " + filePath);
});
Hope this helps anyone facing this issue.
Is there any way to run shell command from JavaScript in node-webkit?
There is a lot of similar questions, but it didn't help me.
I'm trying to build simple desktop app for listing installed tools.
I've created node module 'tools-v' which is installed globally and works when I run it in command line.
This module run several commands: npm -v, node -v, git -v etc.
I'm on Windows 7.
//var sys = require('sys');
var exec = require('child_process').exec;
//var toolsv = (process.platform === "win32" ? "tools-v.cmd" : "tools-v");
$(document).ready(function() {
//myCmd = "C:\\Users\\win7\\AppData\\Roaming\\npm\\tools-v.cmd";
//myCmd = toolsv;
myCmd = 'tools-v';
//gui.Shell.openItem('firefox',function(error, stdout, stderr) { });
//opening Firefox works.
exec(myCmd, function (error, stdout, stderr) {
//detached: true;
console.log('stdout: ' + stdout);
$('#output').append('stdout: ' + stdout)
if (error !== null) {
console.log('exec error: ' + error);
}
});
});
I'm always getting error:
""exec error: Error: spawn ENOENT""
I tried spawn instead of exec. I also tried several other commands, beside node module.
Thanks.
Actually, this code works. I just didn't built full app, I tested it trough sublime build for node-webkit. Preforming full build with grunt solved every spawn issues.
I want to run a command inside of a script tag within my index.html file using node webkit. Is such a thing possible and how would the code look like if I wanted to execute the command 'pwd' for example?
Thanks in advance
Does something like this not work?
var sys = require('sys')
var exec = require('child_process').exec;
var child;
// executes `pwd`
child = exec("pwd", function (error, stdout, stderr) {
sys.print('stdout: ' + stdout);
sys.print('stderr: ' + stderr);
if (error !== null) {
console.log('exec error: ' + error);
}
});
The documentation for node webkit states:
Complete support for Node.js APIs and all its third party modules.
Which would indicate that you could use the node childprocess api:
http://nodejs.org/api/child_process.html
The point of the server is to be able to pick a webcam and stream it, along with a few other things I already have working. I am trying to run a continuous process (mjpg-streamer) from within a node.js server. The node.js server is handling a serving a HTML page that has a select drop down binded to a javascript function to send a command to the server via socket.io. The drop down lets me select video0, video1, and none. However, whenever I try to run the server it refuses saying everything after the a particular block of code is unreachable or the code gets stuck running an infinite process. How can I execute this without locking up the server? Here is the code that causes the problem:
child = exec("video0.sh", function (error, stdout, stderr) {
sys.print('stdout: ' + stdout);
sys.print('stderr: ' + stderr);
if (error !== null) {
console.log('exec error: ' + error);
}
The bash script video0.sh is:
cd mjpg-streamer/mjpg-streamer ;
export LD_LIBRARY_PATH=. ;
./mjpg_streamer -o "output_http.so -w ./www -p 8080" -i "input_uvc.so -d /dev/video0";
you can set a infinite loop in pure shell directly
#!/usr/bin/bash
cd mjpg-streamer/mjpg-streamer ;
export LD_LIBRARY_PATH=. ;
while :
do
./mjpg_streamer -o "output_http.so -w ./www -p 8080" -i "input_uvc.so -d /dev/video0";
sleep 5
done
child = exec("sh video0.sh", function (error, stdout, stderr) {
sys.print('stdout: ' + stdout);
sys.print('stderr: ' + stderr);
if (error !== null) {
console.log('exec error: ' + error);
}
I am working with node.js, and I am trying to embed a console in the web browser to work in a remote server. The web application do the connection so the user does not need to do the ssh username#host but only type commands.
I have tried the node.js' ssh2 module and other modules which use ssh2. But I'm experiencing always the same problem. Every time I execute a command programmatically using exec(), the ssh session is restarted. I'll explain it better with an example.
> ls
returns the content of home directory, one of the directories in the home directory is mydir
> cd mydir
> ls
returns the content of my home directory again, because after a command is executed the ssh session is closed/restarted.
Any node.js library which can do the job? or even a library of other technology different to javascript?
Edit: Other example for clarifying, using the node.js' module ssh-exec
The server has to execute some commands in other machine using ssh. A function in the server contains the following code
var c = exec.connection('username#host.com'); // It takes the ssh key from the default location
exec('cd mydir', c).pipe(process.stdout);
exec('ls -lh', c).pipe(process.stdout);
As you can see I am not ending the connection after the first exec but the output I obtain is the content of the home directory not the content of mydir directory, because the ssh session is reset after each exec.
The maintainer of node.js' ssh2 module provided the solution.
To use the method shell() instead of the method exec().
The method shell() creates an interactive session with the server we are connecting.
The method shell() provides a stream as a parameter of its callback (like the method exec()).
Like when using exec(), stream.on('data', function(data, extended) {...}); can be used to get the output of the commands. However, in this case, to provide commands (input) to the machine you connected with, you need to use stream.write(yourcommand+'\n');
PS. Feel free to edit to improve the accuracy of the answer.
I have to guess a bit, but you do something like child = exec('ssh username#host ls')?
You can do something like
child = exec('ssh username#host');
upfront and in the "loop" of your browser
child.stdin.write('ls\n');
When finished, just close stdin:
child.stdin.end()
which also finishes the child process.
I know this link is old but I figured this may help someone if they're looking for a solution. The
To use the method shell() instead of the method exec().
Works. Here's another solution. Use absolute file paths i.e.
conn.exec("mkdir -p /home/user/Direc/{one,two,three}/", function(err, stream) {
if (err) throw err;
stream.on('data', function(data) {
console.log('STDOUT: ' + data);
}).stderr.on('data', function(data) {
console.log('STDERR: ' + data);
});
});
conn.exec("ls -la /home/user/", function(err, stream) {
if (err) throw err;
stream.on('close', function(code, signal) {
console.log('Stream :: close :: code: ' + code + ', signal: ' + signal);
conn.end();
}).on('data', function(data) {
console.log('STDOUT: ' + data);
}).stderr.on('data', function(data) {
console.log('STDERR: ' + data);
});
});