Search code examples
bashnpmosascriptshelljs

Execute ssh shell script from npm command


I'm trying to write an npm script that will execute an ssh shell command. Currently it's working by executing an osascript command to open a Terminal window and run the command.

I'd like to change this to execute the command in the current terminal. The script is including both shelljs and executive. The script ends without anything happening when I use executive. With shelljs I get:

Pseudo-terminal will not be allocated because stdin is not a terminal. the input device is not a TTY

The command being executed is: ssh -i [ssh-key] -t ubuntu@[ip-address] eval $(base64 -D <<< [command in base64])

The base64 command is sudo docker exec -i -t $(sudo docker ps -aqf "ancestor=' + containerName + '") /bin/bash

If I output the command and copy and paste it, it will work as expected, sshing into a remote machine and running a docker exec command.

If I remove the -t option I don't get the warning messages but there's no output in the console and the script hangs (I assume it's running the command in the background with no output). If I remove the eval ... part I get an output that looks like what you'd see when sshing into a server but without the input terminal.

What can I do to execute this command in the same terminal or in a new tab. If I have to use an osascript command to do this, that's fine as well. I'll be executing this command from the terminal in PhpStorm though.

Edit

Here's the block of code:

var execCommand = 'sudo docker exec -i -t $(sudo docker ps -aqf "ancestor=nginx") /bin/bash';

var buffer = new Buffer(execCommand);
var encoded = buffer.toString('base64');

var cmd = "ssh -i " + this.keyPath + " -t ubuntu@" + ip + " eval $(base64 -D <<< " + encoded + ") ";

shell.exec(cmd);

Edit 2

I can ssh into the machine successfully and get a command prompt but I'm getting a the input device is not a TTY error now when I add the eval command.

var docker_exec = 'sudo docker exec -it $(sudo docker ps -aqf "ancestor=' + containerName + '") /bin/bash';
var encoded = new Buffer(docker_exec).toString('base64');

var sshTerm = spawn('ssh', [
    '-i',
    this.keyPath,
    'ubuntu@' + ip,
    'eval',
    'eval $(base64 -D <<< ' + encoded + ')'
], {
    stdio: 'inherit',
    shell: true
});

sshTerm.on('exit', function() {
    process.exit(0);
});

Solution

  • I checked and it shelljs.exec is good for non TTY commands. For TTY based command you can use normal spawn method. Below is a sample code that works great for me

    var spawn = require('child_process').spawn;
    
    var sshTerm = spawn('ssh', ["[email protected]", ""], {
      stdio: 'inherit'
    });
    
    // listen for the 'exit' event
    //   which fires when the process exits
    sshTerm.on('exit', function(code, signal) {
      if (code === 0) {
        // process completed successfully
      } else {
        // handle error
      }
    });