[英]Spawning a child process with tty in node.js
我正在尝试使用 ssh 在远程服务器上做一些工作——并且 ssh 在本地机器上从 node.js 调用
脚本的精简版本如下所示:
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 中运行命令?
有几个选择:
如果你不介意为你的子进程重用父进程的stdin / stdout / stderr(假设它可以访问一个真正的tty),你可以使用stdio: 'inherit'
(或者如果你想要只inherit
单个流) )在你的spawn()
选项中。
通过pty
模块创建和使用伪tty。 这允许你创建一个“假的”tty,它允许你运行像sudo
这样的程序,而不会实际上将它们连接到真正的tty。 这样做的好处是您可以以编程方式控制/访问stdin / stdout / stderr。
使用像ssh2
这样的ssh模块根本不涉及子进程(并且具有更大的灵活性)。 使用ssh2
您只需将pty: true
选项传递给exec()
, sudo
就可以正常工作。
ssh -qt user@remote.machine -- "sudo mv ./this.thing /to/here/;"
根据ssh手册页 :
-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
某些程序必须运行 tty。 当 tty 输入时,“child_process”库工作不正常。 I have tried for docker ( docker run command like ssh need tty), with microsoft node-pty library https://github.com/microsoft/node-pty
这对我有用。
let command = "ssh"
let args = '-qt user@remote.machine -- "sudo mv ./this.thing /to/here/;"'
const pty = require("node-pty");
let ssh = pty.spawn( command , args.split(" ") )
ssh.on('data', (e)=>console.log(e));
ssh.write("any_input_on_runngin_this_program");
看来您可以使用 FORCE_COLOR 环境变量:
spawn('node', options, {
stdio: 'pipe',
cwd: process.cwd(),
env: {
...{ FORCE_COLOR: 1 },
...process.env
}
})
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.