Question

I'm trying to deploy from GitHub using I want to execute more than one command, in order of the array. The code I'm using now is included below.

async.series([
...
// Deploy from GitHub
function (callback) {
    // Console shizzle:
    console.log('');
    console.log('Deploying...'.red.bold);
    console.log();
    console.log();

    var deployFunctions = [
        {
            command: 'cd ' + envOptions.folder + ' && pwd',
            log: false
        },
        {
            command: 'pwd'
        },
        {
            command: 'su ' + envOptions.user,
            log: false
        },
        {
            command: 'git pull'
        },
        {
            command: 'chmod 0777 * -R',
            log: false
        }
    ];
    async.eachSeries(deployFunctions, function (item, callback) {
        deployment.ssh2.exec(item.command, function (err, stream) {
            deployment.logExec(item);
            stream.on('data', function (data, extended) {
                console.log(data.toString().trim());
                console.log();
            });
            function done() {
                callback(err);
            }

            stream.on('exit', done);
            stream.on('end', done);
        });
    }, function () {
        callback();
    });
},
...);

But, after I cd'ed to the right directory, it forgets where it was and starts all over again.

$ cd /some/folder && pwd
/some/folder

$ pwd
/root
Was it helpful?

Solution

@robertklep is correct about why your cd doesn't persist. Each command invokes a distinct shell instance which starts in its initial state. You could prefix each command with cd /home/jansenstok/domains/alcoholtesterwinkel.com/public_html/ && as a quick fix, but really you are setting yourself up for pain. What you want is a shell script with all the power of multiple lines as opposed to a list of individual disconnected commands.

Look at using ssh2's sftp function to transfer a complete shell script to the remote machine as step 1, execute it via exec (/bin/bash /tmp/your_deploy_script.sh) as step 2, and then delete the script as step 3.

OTHER TIPS

I know this is a super old question, but I ran into this problem while trying to manage an ACE through my Node server. The answer didn't work for me, but several searches later led me to a wrapper that worked really well for me. Just wanted to share here because this was the top link in my Google search. It's called ssh2shell and can be found here: https://www.npmjs.com/package/ssh2shell

It's very simple to use, just pass an array of commands and they run one by one waiting for each command to complete before moving on to the next.

A practical example:

  const client = new Client();
  const cmds = [
    'ls -lah \n',
    'cd /mnt \n',
    'pwd \n',
    'ls -lah \n',
    'exit \n',
  ];
  client.on('ready', () => {
      console.log('Client :: ready');
      client.shell((err, stream) => {
        stream.on('close', (code) => {
          console.log('stream :: close\n', { code });
        }).on('data', (myData) => {
          console.log('stream :: data\n', myData.toString());
        }).on('exit', (code) => {
          console.log('stream :: exit\n', { code });
          client.end();
        }).on('error', (e) => {
          console.log('stream :: error\n', { e });
          rej(e);
        });
        for (let i = 0; i < cmds.length; i += 1) {
          const cmd = cmds[i];
          stream.write(`${cmd}`);
        }
      });
    }).connect({
    host: '127.0.0.1',
    port: 22,
    username: 'root',
    password: 'root',
  });

all the examples in the doc use stream.end() which caused the creation of a new session instead of using the current one.

You cooldn't use "shell" on your program because "Shell" command invokes a new terminal on the system and does your jop. You need to use "exec" command without not emitting "exit" . Default "exec" command emits "exit" command after the command which you gave has been executed.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top