在node.js中使用tty生成子进程

6 javascript ssh tty child-process node.js

我正在尝试使用ssh在远程服务器上做一些工作 - 并且从node.js在本地机器上调用ssh

脚本的精简版本如下所示:

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);
}
Run Code Online (Sandbox Code Playgroud)

我收到了requiretty错误sudo: sorry, you must have a tty to run sudo.

如果我ssh -qt user@remote.machine -- "sudo mv ./this.thing /to/here/;"直接从命令行运行 - 换句话说,直接从tty运行 - 我没有错误,并且this.thing移动/to/there/得很好.

这是部署脚本的一部分,它真的不适合添加!requiretty到sudoers文件.

反正有没有让node.js在tty中运行命令?

msc*_*dex 12

有几个选择:

  • 如果您不介意重新使用父进程的stdin/stdout/stderr(假设它有权访问您的子进程),则可以在选项中使用stdio: 'inherit'(或者只在需要时使用inherit单个流)spawn().

  • 通过pty模块创建和使用伪tty .这允许你创建一个"假的"tty,它允许你运行程序,sudo而不是真正将它们挂钩到真正的tty.这样做的好处是您可以以编程方式控制/访问stdin/stdout/stderr.

  • 使用类似的ssh模块ssh2根本不涉及子进程(并且具有更大的灵活性).有了ssh2你可以简单地传递pty: true选项exec(),并sudo会工作得很好.

  • 尝试第一个要点,运行带有 `stdio: "inherit"` 和 `spawn` 而不是 `exec` 的 `node script.js` 会导致生成的进程上 stdio 的 `null`——但是 `process.stdin.isTTY ` 在`script.js` 中返回`true`。不过,`mv` 命令 _is_ 在另一台机器上成功运行。 (2认同)
  • 因此,换句话说,第一个项目符号可行,但不会让`script.js`的开发人员访问远程进程的stdio. (2认同)