Hysteria child process with tty in node.js

I am trying to do some work on a remote server using ssh - and ssh is being called on the local machine from node.js

A stripped-down version of the script looks like this:

var execSync = require("child_process").execSync;
var command =
  'ssh -qt user@remote.machine -- "sudo mv ./this.thing /to/here/;"';

function callback(error,stdout,stderr) {

  if (error) {
    throw new Error(error,error.stack);


I am getting error requiretty

sudo: sorry, you must have a tty to run sudo


If I run ssh -qt user@remote.machine -- "sudo mv ./this.thing /to/here/;"

directly from the command line - in other words, directly from the tty - I don't get an error, it this.thing

just moves /to/there/


This is part of the deployment script where it would be impractical to add !requiretty

sudoers to the file.

Is there a way to get node.js to run a command on a tty?


source to share

2 answers

There are several options:

  • If you don't mind reusing the stdin / stdout / stderr of the parent process (assuming it has access to the real tty) for your child process, you can use stdio: 'inherit'

    (or just inherit

    separate streams, if you like) in the settings spawn()


  • Create and use pseudo-tty via module pty

    . This allows you to create a "fake" tty that allows you to run programs such as sudo

    without actually connecting them to the real tty. The advantage of this is that you can programmatically control / stdin / stdout / stderr access.

  • Use an ssh module, for example ssh2

    , which doesn't include any child processes at all (and has a lot of flexibility). With, ssh2

    you can just pass the parameter pty: true

    to exec()

    , and it sudo

    will work fine.



ssh -qt user@remote.machine -- "sudo mv ./this.thing /to/here/;"


From the ssh man page :

Force pseudo-terminal allocation. This can be used to execute arbitrary screen programs on a remote machine, which can be very useful, for example. when selling menu services. Lots of -t force tty options even if ssh doesn't have a local tty.

When you run it ssh

interactively, it has a local tty, so the -t option makes it allocate a remote tty. But when you run ssh

inside this script, it has no local tty. The single "-t" makes it skip the remote tty allocation. Specify "-t" twice and it should highlight the remote tty:

ssh -qtt user@remote.machine -- "sudo mv ./this.thing /to/here/;"
      ^^-- Note




All Articles