首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >NodeJS PTY计时命令

NodeJS PTY计时命令
EN

Stack Overflow用户
提问于 2015-09-13 02:53:40
回答 2查看 1.2K关注 0票数 2

我正在尝试使用一个节点进程来启动一个交互式docker会话,然后自动执行一些命令:

代码语言:javascript
复制
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');

这似乎是有效的,唯一的问题是它似乎只是写了所有的命令并触发它们。我似乎无法控制捕获单个命令的输出或错误。

我很好奇有没有更好的方法来解决这个问题?

EN

回答 2

Stack Overflow用户

发布于 2020-05-28 01:25:45

您可以通过管道将流传输到此进程,但不建议这样做。

代码语言:javascript
复制
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。这只是一个简单的问题,改变管道来做这样的事情。

代码语言:javascript
复制
(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键。就像在普通终端中一样,当您执行一个命令时,您不能同时触发第二个命令。这些命令将排队并一个接一个地运行。

输入:

代码语言:javascript
复制
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()
})

输出:

代码语言:javascript
复制
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

票数 1
EN

Stack Overflow用户

发布于 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的回调参数来确定命令何时结束,然后从那里继续执行。像这样的东西可能会起作用:

代码语言:javascript
复制
// 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);
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32542530

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档