1

I'm using grunt, and I need it to execute a script on a remote machine that requires sudo access, and therefore prompts for a password.

I want it to prompt for the password, because I don't want to have to commit the password to source control.

From the command line the following is working correctly:

ssh -t examplehost.com "sudo ls"

However when I run the same command via grunt-exec I get the following:

$ grunt exec:remote_sudo
Running "exec:remote_sudo" (exec) task
>> Pseudo-terminal will not be allocated because stdin is not a terminal.
>> sudo: no tty present and no askpass program specified
>> Sorry, try again.
>> sudo: no tty present and no askpass program specified
>> Sorry, try again.
>> sudo: no tty present and no askpass program specified
>> Sorry, try again.
>> sudo: 3 incorrect password attempts
>> Exited with code: 1.
Warning: Task "exec:remote_sudo" failed. Use --force to continue.

Aborted due to warnings.

The answer to this question with a similar error suggests adding an additional -t switch to force the pseudo-terminal tty allocation.

Doing so gets the password prompt to show, but something isn't right, as it shows my password in the clear as I type it (the usual behaviour shows no output as you type), and it hangs forever:

$ grunt exec:remote_sudo
Running "exec:remote_sudo" (exec) task
[sudo] password for tom: not_my_password
# hangs forever here

What do I need to change to get grunt to run this script? I'm open to alternatives to grunt-exec, but I want to stick with grunt if at all possible.


Example Gruntfile.js for reference:

module.exports = function(grunt) {

  require('load-grunt-tasks')(grunt);

  grunt.initConfig({
    exec: {
      remote_sudo: 'ssh -t examplehost.com "sudo ls"',
    }
  });
};
Community
  • 1
  • 1
tommarshall
  • 2,038
  • 5
  • 23
  • 36

1 Answers1

0

One possible solution is to pipe the password to the command, as seen in this grunt-ssh ticket.

echo password | sudo -S ls

You could pass the password to the task as an argument; something like grunt ssh_task:myPasswordHere. Here's a totally untested Gruntfile that might work:

module.exports = function(grunt) {

  grunt.initConfig({
    exec: {
      remote_sudo: {
        cmd: function(password) {
          return 'echo ' + password + ' | ssh -t examplehost.com "sudo ls"';
        }
      }
    }
  });

  grunt.loadNpmTasks('grunt-exec');

  grunt.registerTask('ssh_task', 'run remote command', function(password) {
    grunt.task.run(['exec:remote_sudo:' + password]);
  });
};

The downside here is that the password is still visible while you're typing it and would be in your shell history.

James
  • 2,626
  • 5
  • 37
  • 51