I'm trying to execute a command in windows using nodes child_process module. The problem is that the application in question (ftp command line in windows) prompts for a username and password. I tried to provide the command with the asked information in the following way:
var ftp = spawn('ftp',['<<ip of server>>']);
var authenticated = false;
var commandsSended = false;
ftp.stdin.write("debug\n");
ftp.stdin.write(os.EOL);
ftp.stdout.on("data", function(data) {
console.log("FTPService: " + data.toString());
if(data.toString().indexOf("226 Transfer complete") > -1) {
ftp.stdin.write('bye\n');
} else if(data.toString().indexOf("Gebruiker") > -1) {
ftp.stdin.write("<<username of server>>");
ftp.stdin.write(os.EOL);
} else if(data.toString().indexOf("Wachtwoord") > -1) {
ftp.stdin.write("<<password of server>>");
ftp.stdin.write(os.EOL);
authenticated = true;
}
if(authenticated && !commandsSended) {
ftp.stdin.write("put " + filePath + " " + newName + "\n");
commandsSended = true;
}
});
ftp.on('exit', function(code) {
if(code > 0) {
console.log("FTPService closed with error " + code);
} else {
console.log("FTPService closed without error");
}
});
This doesn't result in an error, but simply doesn't work. In linux i don't have the problem because i can send the login information as argument with the command. I know that nodejs has it's own module but i need to get it working with the command line (Also other commands need to be performed which will also cause prompts that need to be filled in).
A good practice developing Node applications is to try to make your application as hybrid as possible. When I say hybrid I mean that it should operate identically and seamlessly on the various operating systems it supports. In your case, this means dropping support for the third-party FTP built-in to Windows or Linux and using a FTP client package specifically built for Node.
There are lots of FTP client packages for Node, here's one that's actively developed: node-ftp.
Another one that got more years on its back is jsftp and allows you to hook into the raw FTP socket connection and write arbitrary FTP comnmands to the server.
Related
Have have several droplets on digitalocean and I want to get the remaining disk space on each of them from a node application running on one server to save to a database. I know how to get this info from a remote terminal via the commmand
df -h --output=pcent "/dev/vda1"
but are looking for a solution from the node app. All servers are connected via a vpn but I'm not familar with a way to acheive this, any help would be appreciated.
Try this..
Live demo
On server side in nodejs
const exec = require('child_process').exec;
function getDiskSpace() {
var dir = "/dev/vda1";
var cmd = "df -h --output=pcent " + dir;
exec(cmd, function(err, data) {
if (err) {
// Error handling
console.log("ERROR", err);
} else {
// Sucess response handling
console.log("SUCCESS", data);
}
});
}
Reference
Node - child_process.exec
I have a shell file on the remote machine which will perform certain required actions. Can I call this shell from outside of the VM.
Like by using Azure functions or browser itself.
Here is the Snapshot for shell.
According your needs,I suggest you connecting to a remote server using SSH and execute commands.
I'm not sure which language you are using. So,I just offer java sample code for you here.
You could use SSH component JCraft for remote connection and shell commands invocations.
JSch jsch = new JSch();
String command = "/tmp/myscript.sh";
Session session = jsch.getSession(user, host, 22);
session.connect();
Channel channel = session.openChannel("exec");
((ChannelExec)channel).setCommand(command);
channel.setInputStream(null);
((ChannelExec)channel).setErrStream(System.err);
InputStream in = channel.getInputStream();
channel.connect();
byte[] tmp = new byte[1024];
while (true) {
while (in.available() > 0) {
int i = in.read(tmp, 0, 1024);
if (i < 0) {
break;
}
System.out.print(new String(tmp, 0, i));
}
if (channel.isClosed()) {
if (channel.getExitStatus() == 0) {
System.out.println("Command executed successully.");
}
break;
}
}
channel.disconnect();
session.disconnect();
Also,you could refer to this thread How do I run SSH commands on remote system using Java?.
Hope it helps you. Any concern,please feel free to let me kown.
We're running into a problem where we're getting multiple responses sent from our Node server to a web client which are connected by a socket server (socket.io). By listening with Docklight, I can see that we're really only getting a single response from the serial device, but for some reason the Node server is sending multiples, and they accumulate, so the first time you send a serial command (and it doesn't matter what commands) might only get a couple, next time a couple more, next time a couple more and so on. So if you run several serial commands, you'll get back lots of multiple responses.
Our environment is Windows 7 64 bit, Node V 4.5.0, serialport V 4.0.1. However, this needs to run on Windows, Mac & Linux when we're done. The dev team (me & one other guy) are both fairly new to Node, but otherwise capable developers.
I think what's happening is I'm not using the .flush() & .drain() functions properly and the serialport buffer still contains serial data. Our proprietary devices return either S>, or <Executed/> prompts when a command has completed, so I store the serial response in a buffer until I see one or the other, then process the data (in this example just providing a boolean response whether the device is responding with one or the other or not). For example, if I send a <CR><LF> to one of our devices, it should respond with S> (or <Executed/> depending).
The client calls into the server with this:
socket.on('getDeviceConnected', readDeviceResponse);
function readDeviceResponse(isDeviceResponding) {
console.log('getDeviceConnected');
console.log(isDeviceResponding);
}
function getDeviceConnected() {
console.log("Sending carriage return / line feed.");
socket.emit('getDeviceConnected', '\r\n');
}
And on the server, here's what I'm trying:
socket.on('getDeviceConnected', function (connectionData) {
//write over serial buffer before the write occurs to prevent command accumulation in the buffer.
serialBuffer = '';
sbeSerialPort.write(connectionData, function (err, results) {
//since there's no way to tell if the serial device hasn't responded, set a time out to return a false after allowing one second to elapse
setTimeout(function () {
console.log('Inside getDeviceConnected setTimeout');
console.log('Is serial device responding:', isSerialDeviceResponding);
if (!isSerialDeviceResponding) {
console.log('Serial device timed out.');
socket.emit('getDeviceConnected', false);
}
}, 1000);
if (err) {
console.log('Serial port error level:', err);
}
if (results) {
if (results === 2) {
console.log('Serial port is responding');
}
}
});
sbeSerialPort.on('data', function (serialData) {
isSerialDeviceResponding = true;
console.log('Does S> prompt exist?', serialData.lastIndexOf('S>'));
while(!serialData.lastIndexOf('S>') > -1 || !serialData.lastIndexOf('<Executed/>') > -1){
serialBuffer += serialData;
break;
}
if (isSerialDeviceResponding) {
socket.emit('getDeviceConnected', true);
isSerialDeviceResponding = true;
}
sbeSerialPort.flush(function (err, results) {
if (err) {
console.log(err);
return;
}
if(results){
console.log('Serial port flush return code:', results);
}
});
});
I'm not very sure about the .flush() implementation here, and I've omitted the .drain() part because neither of them seems to do much of anything (assuming they were correctly implemented).
How do I insure that there is no data left in the serialport buffer when the .write() command is complete? Or do you see other problems with how I'm handling the serial data?
Edit, Source code up on pastebin.com:
Server.js
Client.js
HTML
I create some CasperJS scripts that login into Duolingo, do click on a module and open as If I were playing there.
I create a simple meteorJS application and I want that when I click a button be able to execute that casperjs script. I am looking for someone with that experience to help me or oriented me in the right way because I don't have much idea of what can I use to achieve this little personal game.
I have read about RPC - Remote Procedure Call of MeteorJS, and I have read that with PHP and NodeJS you can run a function that executes the script as if I were typing the commands to run the script.
I have found these resources:
ShellJS: https://github.com/shelljs/shelljs
and NodeJS child process: https://nodejs.org/api/child_process.html#child_process_child_process_exec_command_options_callback.
but I don't have much experience, I am doing this to learn more about CasperJS, MeteorJS.
What I need is to be able to run this command -> "casperjs duolingo.js --engine=slimerjs --disk-cache=no" using my Meteorjs app so I can continue creating my little automation bot to play Duolingo totality.
Thank you very much for your help.
it is a "simple" if you know what to do :-)
Just to know what will happen:
1.) You create a method on server side which can run external processes
2.) You create a meteor remote method which can be called by client
3.) You create the action on client and call remote meteor method
4.) You bind the click event to call the action on client
Method to call external processes
process_exec_sync = function (command) {
// Load future from fibers
var Future = Npm.require("fibers/future");
// Load exec
var child = Npm.require("child_process");
// Create new future
var future = new Future();
// Run command synchronous
child.exec(command, function(error, stdout, stderr) {
// return an onbject to identify error and success
var result = {};
// test for error
if (error) {
result.error = error;
}
// return stdout
result.stdout = stdout;
future.return(result);
});
// wait for future
return future.wait();
}
Meteor remote server method
// define server methods so that the clients will have access to server components
Meteor.methods({
runCasperJS: function() {
// This method call won't return immediately, it will wait for the
// asynchronous code to finish, so we call unblock to allow this client
// to queue other method calls (see Meteor docs)
this.unblock();
// run synchonous system command
var result = process_exec_sync('casperjs duolingo.js --engine=slimerjs --disk-cache=no');
// check for error
if (result.error) {
throw new Meteor.Error("exec-fail", "Error running CasperJS: " + result.error.message);
}
// success
return true;
}
})
Client event and remote method call
Template.mytemplate.events({
'click #run-casper': function(e) {
// try to run remote system call
Meteor.call('runCasperJS', function(err, res) {
// check result
if (err) {
// Do some error notification
} else {
// Do some success action
}
});
}
});
Resume
You need to place the server side methods into files on directory "yourproject/server" (e.g.) main.js and the client part into your template with the Button you wish to press (rename mytemplate to your defined one).
Hope you get out what you need.
Cheers
Tom
I'm writing an application that runs from the start-up folder, and tries to connect to a local SQLServer2008-r2 database as part of the startup process of the application. The database i'm connecting to is set to use windows authentication, and my connection string in the application is your standard old connection string:
Data Source=localhost\SQLEXPRESS;Initial Catalog=MyDatabase;Integrated Security=True
The code to actually establish the connection looks like this:
String connectionstring = "Data Source=localhost\SQLEXPRESS;Initial Catalog=MyDatabase;Integrated Security=True";
SqlConnection cn = new SqlConnection(connectionstring);
bool databaseUp = false;
void Start()
{
CheckSQLService();
for (int i = 0; i < 600; i++)
{
if (ConnectToDB())
{
Console.WriteLine("Database is up and running.");
databaseUp = true;
}
else
{
Console.WriteLine("Database Connection Failed");
CheckSQLService();
Console.WriteLine("Trying again");
Thread.Sleep(1000);
}
}
if(!databaseUp)
{
Console.WriteLine("Database Not Connected: exited loop.");
}
}
bool ConnectToDB()
{
try
{
cn.Open();
return true;
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
return false;
}
}
void CheckSQLService()
{
System.ServiceProcess.ServiceController SC = new System.ServiceProcess.ServiceController("MSSQL$SQLEXPRESS");
Console.WriteLine(" = = = Checking SQL Service Status: = = = "
+ "\n ServiceName : " + SC.ServiceName
+ "\n State : " + SC.Status
+ "\n Stoppable : " + SC.CanStop
+ "\n Pausable : " + SC.CanPauseAndContinue
+ "\n Can Shutdown: " + SC.CanShutdown);
}
Basically I loop until I get a connection, and if it fails, I sleep and try again.
Most of the time (about 60%) I am able to successfully establish a connection with no problem on first try. Sometimes, it takes several attempts for this to be successful, and the application waits for some time. I will also note that the read-out of CheckSQLService() verifies every time I call it that the SQL service is running - Only sometimes it rejects my windows credentials apparently.
Anybody have ideas why this might be happening intermittently? Again this is part of an application that runs when windows first starts up, so there could may understandably be many factors at play (e.g. other processes or services not fully loaded, or starting at same time etc).
Just because the SQL Server service is running does not mean it is ready to accept connections.
Since you are always able to connect eventually, and your program runs as the computer is booting, I strongly suspect that you sometimes run before SQL Server is fully initialized and ready for connections.
Many things happen during a typical boot sequence. It is not surprising that your program is sometimes running before SQL Server is ready, and vice-versa.