12

From nodejs I have been trying to execute linux commands on remote server and get the output in stream for further processing. For connecting to remote linux server , I have all necessary details like serverip, username and password. I searched a lot on internet and found that this can be achieved by ssh.

Can Nodejs ui page run shell cmd to remote machine and run script

But this answer a bit confusing and I didn't get how to use password in connection.

Pointer to any working example would be great help.

5 Answers 5

12

I solved the problem myself. There is one npm package (ssh-exec) available for ssh command execution. Below is the code I used.

var exec = require('ssh-exec')
var v_host = 'XX.XX.XX.XXX'
exec('ls -lh', {
  user: 'root',
  host: 'XX.XX.XX.XXX', 
  password: 'password'
}).pipe(process.stdout , function (err, data) {
    if ( err ) { console.log(v_host); console.log(err); }
  console.log(data)
})
Sign up to request clarification or add additional context in comments.

5 Comments

This doesn't work keeps giving me an error "throw error" on events class
@Nikhil, hope you have verified the connectivity using Putty. Please confirm.
Yes I did, and still it doesn't work. I found a better solution to the problem though.
What would be await/async syntax for this I am trying to figure it out?
@usersam Is it possible to do that without ssh connection? I search for something like weavely in php
6

I also used another package "simple-ssh" to solve this purpose. It is very simple to use and gives good control over output which can be used like a stream.

var SSH = require('simple-ssh');

var ssh = new SSH({
    host: 'XX.XX.XX.XXX',
    user: 'username',
    pass: 'password'
});

ssh.exec('ls -lh', {
    out: function(stdout) {
        console.log(stdout);
    }
}).start();

And to END execution on demand

ssh.end();

Where ssh is nothing but the new SSH we have declared previously.

3 Comments

Of the top three mentioned here, this is the only one that worked without having to fix anything circa 2021.
I seem to have a problem with the The authenticity of host 'xx.xx.xxx.xxx' can't be established. And with all nodejs ssh packages the code just hangs. I tried from command line and it asked me if I trust the host, after typing yes ssh work from command line but how can I put yes this with nodejs?
simple-ssh is no longer maintained.
3

Node comes with this default library 'remote-exec', which can be used for remote ssh. It worked for me.

var rexec = require('remote-exec');

module.exports = function (context, req) {
    var connection_options = {
    port: 443,
    username: 'yourusername',
    password: 'yourpassword'
    };

    var hosts = [
        'yourhostname.com'
    ];

    var cmds = [
     'ls -lh'
    ];

    rexec(hosts, cmds, connection_options, function(err){
        if(err){
            context.log(err);
        }else{
         context.log("Success!!");
        }
    });
};

2 Comments

Yes this also works but I also used "simple-ssh" which i felt better than this.I would advice to give it a try. anyway , i have been struggling to execute command on remote WINDOWS server in same way, without making much change on remote m/c. If you have come across to some node.js solution please let me know. Thanks
I don't think it is true that "Node comes with this default library 'remote-exec'" -- I think you would have to install it as it seems to be provided by someone named tpresley (github.com/tpresley/node-remote-exec). When my script includes require('remote-exec');, I get "Error: Cannot find module 'remote-exec'" because Node.js does not come with this library by default.
1

came across this post while looking for solution to execute a script on remote [aws] Linux server. Used ssh2 package and the below code worked good -

var Client = require('ssh2').Client;

var conn = new Client();
conn.on('ready', function() {
  console.log('Client :: ready');

  // const cmd = 'uptime';
  const cmd = 'ls -l /tmp | grep jetty';

  conn.exec(cmd , function(err, stream) {
    if (err) throw err;
    stream.on('close', function(code, signal) {
      console.log('SSH 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);
    });
  });
}).connect({
  host: 'ec2-##-###-###-###.ap-xxxx-1.compute.amazonaws.com',
  username: 'xyz',
  privateKey: require('fs').readFileSync('../my_private.ppk')
});

ref: https://www.npmjs.com/package/ssh2
also install ssh2 using npm i ssh2

sample run of the above:

E:\nodejs>node ex-ssh2.js
Client :: ready
STDOUT: drwxr-xr-x 2 jenkins jenkins    4096 Jul 17 13:35 jetty-0.0.0.0-8080-war-_-any-3087978102711715755.dir

SSH Stream :: close :: code: 0, signal: undefined

2 Comments

this may be a good option but what about passing command arguments. Like "simple-ssh" gives option "args: [arg1, arg2, ..]"
in the above example, cmd has arguments 'ls -l /tmp | grep jetty'; whereas simple-ssh has advanced options such as running queue of commands. however ssh2 should be fine if requirement is to execute a script on remote m/c that may optionally take arguments
1

For me the simplest way worked :

Run the ssh commnad from process_child.exec like executing it from bash :

    const childProcess = require('child_process');
    const util = require('util');
    const exec = util.promisify(childProcess.exec).bind(childProcess);
    async function connect() {
        
     try{
       let stdout = await exec(`sudo chmod 400 /home/ubuntu/.ssh/id_rsa
          sudo ssh -i "/home/ubuntu/.ssh/id_rsa" [email protected] ls`);
       console.log(stdout);
     }catch(err){
       console.log('error' , err)
     }
   }
        
   connect();

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.