我正在尝试使用一个节点进程来启动一个交互式docker会话,然后自动执行一些命令:
var spawn = require('pty.js').spawn;
var proc = spawn('docker', [ 'run', '-i', '-t', 'mycontainer' ], {
name: 'test',
rows: 30,
cols: 200,
cwd: process.env.HOME,
env: process.env
});
proc.on('data', function (data) {
console.log(data);
});
proc.write('cd /tmp');
proc.write('nvm install 0.10\r');
proc.write('npm install');
这似乎是有效的,唯一的问题是它似乎只是写了所有的命令并触发它们。我似乎无法控制捕获单个命令的输出或错误。
我很好奇有没有更好的方法来解决这个问题?
发布于 2020-05-28 01:25:45
您可以通过管道将流传输到此进程,但不建议这样做。
const { pipeline } = require('stream');
const { spawn } = require('node-pty')
const proc = spawn('docker', ['run', '--rm', '-ti', 'alpine', '/bin/sh'], {
name: 'xterm-color',
cwd: process.env.HOME,
env: process.env,
encoding: null,
});
pipeline(process.stdin, proc, (err) => err && console.warn(err.message))
pipeline(proc, process.stdout, (err) => err && console.warn(err.message))在流中不使用pty的maintainer have suggested。这只是一个简单的问题,改变管道来做这样的事情。
(async (stream) => {
for await (const chunk of stream) {
proc.write(chunk.toString())
}
})(process.stdin).catch(console.warn)要点是我们应该将字符串传递给write函数。我们也应该期待字符串作为它的输出。因此,我们不应该在对象中设置任何编码,使其在默认情况下输出utf8字符串。
关于你最初的问题。proc.write('ls\r')是正确的方法。注意后面的\r,实际上是按enter键。就像在普通终端中一样,当您执行一个命令时,您不能同时触发第二个命令。这些命令将排队并一个接一个地运行。
输入:
const { spawn } = require('node-pty')
const proc = spawn('docker', ['run', '--rm', '-ti', '--network=host', 'node', '/bin/sh'], {
name: 'xterm-color',
cwd: process.env.HOME,
env: process.env,
});
proc.write('npm init -y\r')
proc.write('npm i eslint\r')
proc.write('ls node_modules /\r')
const disposable = proc.onData((text) => process.stdout.write(text))
const exitDisposable = proc.onExit(() => {
disposable.dispose()
exitDisposable.dispose()
})输出:
npm i eslint
ls node_modules /
# Wrote to /package.json:
{
"name": "",
"version": "1.0.0",
"description": "",
"main": "index.js",
"directories": {
"lib": "lib"
},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC"
}
npm notice created a lockfile as package-lock.json. You should commit this file.
npm WARN @1.0.0 No description
npm WARN @1.0.0 No repository field.
+ eslint@7.1.0
added 136 packages from 82 contributors and audited 136 packages in 9.461s
9 packages are looking for funding
run `npm fund` for details
found 0 vulnerabilities
# /:
bin etc lib64 node_modules package.json run sys var
boot home media opt proc sbin tmp
dev lib mnt package-lock.json root srv usr
node_modules:
@babel is-extglob
@types is-fullwidth-code-point
...
...
# 您可以看到,它在npm安装完成之前编写了ls,但在安装完成后运行。
还要注意,对于docker args,我使用了-ti,而不仅仅是-t。
发布于 2015-09-13 03:09:45
查看pty.js模块的源代码,可以清楚地看到您的proc.write实际上就是标准的节点net.Socket.write -- https://nodejs.org/api/net.html#net_socket_write_data_encoding_callback
简而言之,是的,您只是将命令发送到套接字。在执行下一个命令之前,您需要等待每个命令完成。因此,您需要使用.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);https://stackoverflow.com/questions/32542530
复制相似问题