Javascript NodeJS PTY定时命令
我尝试使用节点进程启动交互式docker会话,然后自动执行一些命令:Javascript NodeJS PTY定时命令,javascript,node.js,pty,Javascript,Node.js,Pty,我尝试使用节点进程启动交互式docker会话,然后自动执行一些命令: var spawn=require('pty.js').spawn; var proc=spawn('docker',['run','-i','-t','mycontainer',]{ 名称:'测试', 行:30, 科尔斯:200, cwd:process.env.HOME, env:process.env }); 过程on('data',函数(data){ 控制台日志(数据); }); 过程写入(“cd/tmp”); 进程
var spawn=require('pty.js').spawn;
var proc=spawn('docker',['run','-i','-t','mycontainer',]{
名称:'测试',
行:30,
科尔斯:200,
cwd:process.env.HOME,
env:process.env
});
过程on('data',函数(data){
控制台日志(数据);
});
过程写入(“cd/tmp”);
进程写入('nvm安装0.10\r');
过程写入(“npm安装”)代码>查看pty.js
模块的源代码,很明显您的proc.write
实际上是标准节点net.Socket.write
--
简言之,是的,您只是在向套接字发送命令。在执行下一个命令之前,需要等待每个命令完成。因此,您需要使用回调参数.write
来确定命令何时完成,然后从那里继续。类似的方法可能会奏效:
// this is a quick and dirty hack
let cmdcount = 0;
function submitcmd() {
switch (cmdcount) {
case 0:
proc.write('nvm install 0.10\r', 'utf8', submitcmd);
break;
case 1:
proc.write('npm install', 'utf8', submitcmd);
break;
}
cmdcount += 1;
}
proc.write('cd /tmp', 'utf8', submitcmd);
您可以将流输送到此流程,但不建议这样做
const{pipeline}=require('stream');
const{spawn}=require('node-pty')
const proc=spawn('docker',['run','-rm','-ti','alpine','/bin/sh']{
名称:“xterm颜色”,
cwd:process.env.HOME,
env:process.env,
编码:空,
});
管道(process.stdin,proc,(err)=>err&&console.warn(err.message))
管道(proc,process.stdout,(err)=>err&&console.warn(err.message))
用户不能像流一样在中使用pty。这只是一个简单的问题,改变管道为这样的东西
(异步(流)=>{
用于等待(流的常量块){
进程写入(chunk.toString())
}
})(process.stdin).catch(console.warn)
要点是我们应该将字符串传递给write函数。我们还应该期望字符串作为其输出。因此,我们不应该在对象中设置任何编码,使其默认输出utf8字符串
关于你最初的问题<代码>过程写入('ls\r')
是正确的方法。请注意尾随的\r
几乎按enter键。就像在普通终端中一样,当执行命令时,不能同时触发第二个命令。命令将排队并一个接一个地运行
输入:
const{spawn}=require('node-pty')
const proc=spawn('docker',['run','-rm','-ti','-network=host','node','/bin/sh']{
名称:“xterm颜色”,
cwd:process.env.HOME,
env:process.env,
});
进程写入('npm init-y\r')
进程写入('npm i eslint\r')
进程写入('ls节点\u模块/\r')
const disposable=proc.onData((文本)=>process.stdout.write(文本))
const exitDisposable=proc.onExit(()=>{
一次性处置
exitDisposable.dispose()
})
输出:
npm i eslint
ls节点单元/
#写入/package.json:
{
“名称”:“,
“版本”:“1.0.0”,
“说明”:“,
“main”:“index.js”,
“目录”:{
“lib”:“lib”
},
“脚本”:{
“测试”:“echo\”错误:未指定测试\“&退出1”
},
“关键词”:[],
“作者”:“作者”,
“许可证”:“ISC”
}
npm通知创建了一个锁文件,名为package-lock.json。你应该提交这个文件。
npm警告@1.0.0无说明
npm WARN@1.0.0无存储库字段。
+ eslint@7.1.0
在9.461s中添加了来自82个贡献者的136个包,并审核了136个包
9个方案正在寻求资金
有关详细信息,请运行“npm基金”
发现0个漏洞
# /:
bin etc lib64 node_modules package.json运行系统变量
在tmp中启动主媒体opt proc SBI
dev lib mnt package-lock.json根srv usr
节点单元模块:
@巴别塔是一个地球仪
@类型是全宽度代码点
...
...
#
您可以看到,它在npm安装完成之前编写了ls,但之后才运行
还请注意,我对docker参数使用了
-ti
而不是-t
。对不起,这是proc
,我只是打错了。如果您不介意用另一种语言做这件事,传统的处理方法是使用基于tcl的expect(您将使用tcl编程,但expect是用C编写的)我真正要做的是将proc.write
函数包装成这样,这样我就可以使用Promise
API来简单地链接我想要发出的命令。我已经把它放在那里了,但它只是触发第一个命令,好像它甚至没有命中回调一样。我将它改为使用proc.socket.write()
它现在通过命令触发,尽管它仍然会在前面显示所有命令,就像它只是在所有事情中移动一样。您可能会发现自己生成流程比通过pty库更容易——知道从生成的流程在stdin中生成管道的任何好例子吗?