工具集的历史

工具集的历史

给定一个命令,当其输出进入终端时改变其行为(例如,产生彩色输出),如何在管道中重定向该输出,同时保留更改的行为?一定有一个我不知道的实用程序。

某些命令(例如grep --color=always)具有强制执行行为的选项标志,但问题是如何解决仅依赖于测试其输出文件描述符的程序。

如果重要的话,我的 shell 在bashLinux 上。

答案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现在被拼写为“ Ginsu ptybandage”,它是“Ginsu”的同义词ptyget ptyio -t ptyspawnpty -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 源包附带了类似的工作ptybandangeptyrun脚本,它们使用 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

进一步阅读

答案2

您可能会通过使用获得您需要的东西unbuffer

unbuffer是一个tcl/expect脚本。如果需要的话请查看来源。另请注意 man 中的 CAVEATS 部分。

另请注意,它不执行别名,例如:

alias ls='ls --color=auto'

除非添加 Stéphane Chazelas 指出的技巧:

如果您执行 a alias unbuffer='unbuffer '(注意尾随空格),则别名将在 后扩展unbuffer

答案3

您可以使用索卡特开始你的流程普蒂连接,并让 socat 将 pty 的另一端连接到文件。哪个 AFAIU 正是您所问的:

socat EXEC:"my-command",pty GOPEN:mylog.log

这种方法会导致isatty调用来my-command返回true,并且仅依赖于此的进程将被愚弄以输出控制代码。请注意,某些进程(特别是grep)还会检查环境变量的值TERM,因此您可能需要将其设置为合理的值,例如"xterm"

答案4

使用怎么样script(1)

例如:

script -q -c 'ls -G' out_file

将保存ls输出并out_file保留颜色代码。

相关内容