Spawning a child process with tty in node.js

一笑奈何 提交于 2021-02-16 04:44:07

问题


I am trying to do some work on a remote server using ssh--and ssh is 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/;"';
execSync(command,callback);

function callback(error,stdout,stderr) {

  if (error) {
    console.log(stderr);
    throw new Error(error,error.stack);
  }
  console.log(stdout);
}

I get the requiretty error 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 a tty--I get no error, and this.thing moves /to/there/ just fine.

This is part of a deploy script where it really wouldn't be ideal to add !requiretty to the sudoers file.

Is there anyway to get node.js to run a command in a tty?


回答1:


There's a few options:

  • If you don't mind re-using stdin/stdout/stderr of the parent process (assuming it has access to a real tty) for your child process, you can use stdio: 'inherit' (or only inherit individual streams if you want) in your spawn() options.

  • Create and use a pseudo-tty via the pty module. This allows you to create a "fake" tty that allows you to run programs like sudo without actually hooking them up to a real tty. The benefit to this is that you can programmatically control/access stdin/stdout/stderr.

  • Use an ssh module like ssh2 that doesn't involve child processes at all (and has greater flexibility). With ssh2 you can simply pass the pty: true option to exec() and sudo will work just fine.




回答2:


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

Per the ssh man page:

-t
Force pseudo-terminal allocation. This can be used to execute arbitrary screen-based programs on a remote machine, which can be very useful, e.g. when implementing menu services. Multiple -t options force tty allocation, even if ssh has no local tty.

When you run ssh interactively, it has a local tty, so the "-t" option causes it to allocate a remote tty. But when you run ssh within this script, it doesn't have a local tty. The single "-t" causes it to skip allocating a remote tty. Specify "-t" twice, and it should allocate a remote tty:

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


来源:https://stackoverflow.com/questions/31866207/spawning-a-child-process-with-tty-in-node-js

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!