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

时间:2015-08-06 21:35:22

标签: javascript node.js ssh child-process tty

我正在尝试使用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);
}

我收到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中运行命令?

2 个答案:

答案 0 :(得分:11)

有几个选择:

  • 如果您不介意重新使用父进程的stdin / stdout / stderr(假设它有权访问您的子进程),可以使用stdio: 'inherit'(或inherit选项中仅spawn()个别流。

  • 通过pty模块创建并使用伪tty。这允许你创建一个假的" tty允许你运行sudo之类的程序而不实际将它们连接到真正的tty。这样做的好处是可以通过编程方式控制/访问stdin / stdout / stderr。

  • 使用像ssh2这样的ssh模块根本不涉及子进程(并且具有更大的灵活性)。使用ssh2,您只需将pty: true选项传递给exec()sudo就可以正常使用。

答案 1 :(得分:1)

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

根据ssh man page

  

<强> -t
  强制伪终端分配。这可以用来执行任意的   基于屏幕的程序在远程机器上,可以是非常的   有用的,例如实现菜单服务时。多个-t选项   强制tty分配,即使ssh没有本地tty。

当您以交互方式运行ssh时,它具有本地tty,因此“-t”选项会使其分配远程tty。但是当您在此脚本中运行ssh时,它没有本地tty。单个“-t”使它跳过分配远程tty。指定“-t”两次,它应该分配一个远程tty:

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