node.js - 有没有办法从我的 Node.js 生成的 shell 标准输出文本中挽救这些损坏的 bash 转义序列工件?
问题描述
我写了一个类用于生成和与 shell(在 Electron 应用程序中)交互,如下所示:
const { spawn } = require('child_process')
class Shell {
constructor() {
this.process = spawn('/bin/bash', []);
this.process.stdout.on('data', (data) => {
const out = data.toString()
console.log('stdout:', out)
if (this.res) {
this.res(out)
}
});
this.process.stderr.on('data', function (data) {
const err = data.toString()
console.log('stderr:', err)
if (this.rej) this.rej(err)
});
}
send(command, throwErr = false) {
return new Promise((resolve, reject) => {
this.res = resolve
if (throwErr) this.rej = reject
else this.rej = resolve
this.process.stdin.write(command + '\n')
})
}
}
我得到的输出是这样的:
stdout: ]0;student@linux-opstation-jyrf: ~[01;32mstudent@linux-opstation-jyrf[00m:[01;34m~[00m$
这是我使用 JSON 对输出进行字符串化以查看转义字符的版本:stdout: "\u001b]0;student@linux-opstation-jyrf: ~\u0007\u001b[01;32mstudent@linux-opstation-jyrf\u001b[00m:\u001b[01;34m~\u001b[00m$ ssh -t -t -oStrictHostKeyChecking=no student@10.5\r50.30.231\r\n"
我意识到这些是用于格式化的 bash 转义序列中的伪影,我无法弄清楚如何摆脱它,特别是因为没有打印转义字符。
编辑:所以我将原始标准输出Buffer
(data
在代码中)写入二进制文件:
fs.createWriteStream(path, { encoding: 'binary'}).write(data);
并发现该方法似乎没有发生任何损失.toString()
(我认为?)所以我只好挠头,其余的标准输出标记被截断。
00000000: 1b5d 303b 7374 7564 656e 7440 6c69 6e75 .]0;student@linu
00000010: 782d 6f70 7374 6174 696f 6e2d 6a79 7266 x-opstation-jyrf
00000020: 3a20 7e07 1b5b 3031 3b33 326d 7374 7564 : ~..[01;32mstud
00000030: 656e 7440 6c69 6e75 782d 6f70 7374 6174 ent@linux-opstat
00000040: 696f 6e2d 6a79 7266 1b5b 3030 6d3a 1b5b ion-jyrf.[00m:.[
00000050: 3031 3b33 346d 7e1b 5b30 306d 2420 7373 01;34m~.[00m$ ss
00000060: 6820 2d74 202d 7420 2d6f 5374 7269 6374 h -t -t -oStrict
00000070: 486f 7374 4b65 7943 6865 636b 696e 673d HostKeyChecking=
00000080: 6e6f 2073 7475 6465 6e74 4031 302e 350d no student@10.5.
00000090: 3530 2e33 302e 3233 310d 0a 50.30.231..
但也许我在保存文件时没有正确编码,因为我认为原始缓冲区应该(?)输出这样的文本\u001b[00m:\u001b[01;34m
并且\uFFFF
十六进制字符不存在。编辑:啊,\uFFFF
显然是unicode。仍在弄清楚如何将该缓冲区正确保存为二进制文件,我认为使用{encoding: 'binary'}
set 作为选项会丢失 unicode。否则十六进制转储只显示 utf8,这听起来更有可能。
解决方案
假设这些工件确实来自定制的提示字符串,最简单的做法是更改提示字符串。有多种替代方法,这在某种程度上取决于提示字符串的设置位置。
如果您得到提示,则bash
作为交互式 shell 运行。它不会使用您用来启动它的命令作为登录 shell 运行。因此,相关的初始化步骤如下:
当一个不是登录 shell 的交互式 shell 启动时,bash 读取并执行来自
~/.bashrc
的命令(如果该文件存在)。这可以通过使用--norc选项来禁止。--rcfile 选项将file
强制bash从 file 而不是~/.bashrc
.
(Bash 手册页)
因此,您可以通过--norc
选项来bash
禁止读取任何 shell 初始化文件,从而获得默认提示(以及其他所有内容)。但是那个环境可能对您的需求来说太稀疏了,因此作为替代方案,您可以创建一个专用的 shell 配置文件来设置您想要的确切配置,并使用该--rcfile
选项使bash
您的程序启动的实例使用它。 这可能是您最好的选择,但可能需要一些工作才能根据需要进行设置。
作为一种更快更脏的替代方法,您可以修改相关~/.bashrc
以更改提示字符串(删除 and 的定义PS1
,PS2
或者将它们重新定义为默认值:)PS1='\s-\v\$ ' PS2='> '
。您还可以将前两个与自定义配置文件结合起来,该文件读取默认配置文件并覆盖提示字符串:
电子.bashrc
. ~/.bashrc
PS1='\s-\v\$ '
PS2='> '
推荐阅读
- linux - 从私有 docker 注册表下载后,可以重新分发 docker 映像吗?
- javascript - JavaScript - 如何使用 appendChild 创建结构良好的元素?
- git - 更改由 openSSL 生成的 TFS SSL 证书后克隆 git repo 失败
- facebook-graph-api - 一批通知大约需要 10 秒
- android - 重置手机后谁负责将键盘设置为默认值
- react-native - React Native 下拉菜单无法点击
- java - JAVA:多线程代码在 Web 应用程序中的影响
- python - Python 3 - Scapy 嗅探过滤器选项
- angular - Http获取参数过滤器
- python - 使用 Python 和 SQLAlchemy 从 Google Cloud Function 连接到 Cloud SQL