给定一个命令,当其输出进入终端时改变其行为(例如,产生彩色输出),如何在管道中重定向该输出,同时保留更改的行为?一定有一个我不知道的实用程序。
某些命令(例如grep --color=always
)具有强制执行行为的选项标志,但问题是如何解决仅依赖于测试其输出文件描述符的程序。
如果重要的话,我的 shell 在bash
Linux 上。
答案1
工具集的历史
您不是第一个想要这样的工具的人。 30 年来人们一直想要这样的工具。它们也已经存在了差不多那么久了。
此类事情最早的工具是 Daniel J. Bernstein 的“pty”包,Rich Salz 将其描述为“Ginsu 刀”,Bernstein 在 20 世纪 90 年代初写了这个包,以便在 nethack 上作弊(原文如此!)。 “pty”包的第 4 版于 1992 年发布comp.sources.unix
(第 25 卷第 127 至 135 期)。它仍然可以在万维网上找到。 Paul Vixie 当时这样描述:
我能说什么?它切片、切丁、洗碗、遛狗。它“只是工作”,这意味着如果您按照说明进行操作,您将获得一个工作包,而无需任何拉扯头发或咬牙切齿或其他标准移植活动。
Bernstein 后来在 1999 年 4 月 7 日或之前更新了此内容,使用了“ptyget”包,他宣布:
我组装了一个新的伪 tty 分配器 ptyget。 alpha 版本位于
ftp://koobera.math.uic.edu/pub/software/ptyget-0.50.tar.gz
.有一个 ptyget 邮件列表;要加入,请发送一条空消息至[email protected]
。我从头开始设计了 ptyget 的界面。它比 pty 更加模块化;基本的 pty 接口现在已分为三部分:
ptyget
:一个微小的低级程序 - 包中唯一的 setuid 程序 - 分配一个新的伪 tty 并将其传递给您选择的程序ptyspawn
:另一个小程序,在伪终端下运行子进程,等待它退出并观察停止情况ptyio
:另一个稍微大一点的程序,可以来回移动数据旧的“Ginsu”刀
pty
现在被拼写为“ Ginsuptybandage
”,它是“Ginsu”的同义词ptyget ptyio -t ptyspawn
;pty -d
,用于将网络程序附加到伪 ttys,现在拼写为,它是;ptyrun
的同义词。ptyget ptyio ptyspawn
并且nobuf
是 的同义词ptyget ptyio -r ptyspawn -23x
。我已将会话管理功能分成一个单独的包。
那个单独的包是“sess”包。
顺便说一句,“ptyget”因举例说明了 Berstein 自己从未发布的“重做”构建系统的一个非常早期的版本,也是为数不多的已发布实例之一而闻名。 dependon
是一个明显的先兆redo-ifchange
。
用法
ptybandage
ptybandage
是人们在登录会话中通常想要的。其主要用例是使对其标准输入、输出或错误是否连接到终端敏感的程序以这种方式运行,即使它们实际上位于 shell 管道中,或者将其标准文件描述符重定向到文件。
它需要一个命令来运行(当然,它必须是一个正确的外部命令),并以它认为其标准输入、输出和错误附加到终端的方式运行它,通过将它们连接到ptybandage
's原始标准输入、输出和错误。
它处理在作业控制 shell 下运行的细微差别,确保终端 STOP 字符不仅停止ptybandage
,而且停止附加到内部终端运行的程序。
ptyrun
ptyrun
是人们通常想要的 TCP 网络服务器。它的主要用例是远程执行环境,这些环境本身没有设置终端,运行的程序在没有终端时无法按预期运行。
它不希望在作业控制 shell 下运行,并且如果正在运行的命令收到停止信号,则只需重新启动即可。
可用的工具集
Dru Nelson 发布了“pty”版本 4 和“ptyget”。
Paul Jarc 发布了 ptyget 的固定版本,它试图处理操作系统实际上不再提供的原始版本中特定于操作系统的伪终端设备 ioctl。
nosh 源包附带了类似的工作ptybandange
和ptyrun
脚本,它们使用 Laurent Bercot 的execline
工具和 nosh 包自己的伪终端管理命令。从 nosh 版本 1.23 开始,这些可以预先打包在 nosh-terminal-extras 包中。 (早期版本仅向从源代码构建的人提供它们。)
一些示例用途
Jurjgen Oskamptybandage
在 AIX 上使用将此处文档的输入提供给显式打开并读取其控制终端以获取密码提示的程序:
$ ptybandage dsmadmc <<EOF >uit.txt 约斯卡姆 密码 查询会话 查询过程 辞职 EOF
ptyrun
安迪·布拉德福德 (Andy Bradford)在 OpenBSD 上使用在 daemontools 和 ucspi-tcp 下,使bgplgsh
交互式路由器控制程序可通过网络访问,同时使其认为正在与终端通信:
#!/bin/sh 执行2>&1 执行 envuidgid rviews tcpserver -vDRHl0 0 23 ptyrun /usr/bin/bgplgsh
进一步阅读
- 丹尼尔·伯恩斯坦 (1992-02-19)。 v25i127:伪 tty 设备的通用接口。 comp.sources.unix。 25(127)。
- 丹尼尔·伯恩斯坦 (1991-10-04)。 会话管理简介。伯恩斯坦在 TTY 上。 JdeBP。
- 保罗·雅尔克. 普蒂盖特。 Paul Jarc 的软件。
- 乔纳森·德博因·波拉德 (2016)。Daniel J. Bernstein 的 ptyget 工具集。软件。
- 德鲁·纳尔逊. 德鲁德鲁/pty4。 GitHub。
- 德鲁·纳尔逊. 德鲁德鲁/普蒂盖特。 GitHub。
- 洛朗·贝尔科特.执行。软件。
- 乔纳森·德博因·波拉德 (2016)。 Daniel J. Bernstein 的软件合一。软件。
- 乔纳森·德博因·波拉德 (2014)。 小吃包。软件。
- 乔纳森·德博因·波拉德 (2012)。 简介
redo
。常见答案。 - 雷克·弗洛特。
bgplgsh
。 8. OpenBSD 手册页。
答案2
您可能会通过使用获得您需要的东西unbuffer
。
unbuffer
是一个tcl
/expect
脚本。如果需要的话请查看来源。另请注意 man 中的 CAVEATS 部分。
另请注意,它不执行别名,例如:
alias ls='ls --color=auto'
除非添加 Stéphane Chazelas 指出的技巧:
如果您执行 a alias unbuffer='unbuffer '
(注意尾随空格),则别名将在 后扩展unbuffer
。
答案3
答案4
使用怎么样script(1)
?
例如:
script -q -c 'ls -G' out_file
将保存ls
输出并out_file
保留颜色代码。