Answers:
通过使用,您可能会得到所需的东西unbuffer
。
unbuffer
是一个tcl
/ expect
脚本。如果需要,请查看源。另请注意man上的CAVEATS部分。
还要注意,它不执行别名,例如:
alias ls='ls --color=auto'
除非有人添加StéphaneChazelas指出的技巧:
如果执行alias unbuffer='unbuffer '
(注意尾随空格),则别名将在后面展开unbuffer
。
alias unbuffer='unbuffer '
(注意尾随空格),则别名将在后面展开unbuffer
。
unbuffer
它是!sudo apt install expect
-不清楚。
您不是第一个想要这种工具的人。人们一直想要这样的工具已有30年了。它们已经存在了将近这么长时间。
此类工具的最早工具是Daniel J. Bernstein的“ pty”软件包,Rich Salz将其描述为“ Ginsu刀”,Bernstein在1990年代初写信以便欺骗nethack(原文如此!)。“ pty”软件包的第4版发布于1992年comp.sources.unix
(第25卷,第127至135期)。它仍然可以在万维网上找到。Paul Vixie当时对此进行了描述:
我能说什么 它切成薄片,切成小方块,洗碗,walk狗。它“行之有效”,这意味着,如果您按照说明进行操作,您将得到一个有效的包装,而无需拉扯头发或咬牙切齿或进行其他标准的移植活动。
伯恩斯坦后来在1999年4月7日或之前用“ ptyget”软件包对此进行了更新,他宣布:
我整理了一个新的伪tty分配器ptyget。Alpha版本位于
ftp://koobera.math.uic.edu/pub/software/ptyget-0.50.tar.gz
。有一个小巧的邮件列表。要加入,请向发送空消息djb-ptyget-requ...@koobera.math.uic.edu
。我从头开始设计ptyget的界面。它比pty更具模块化。现在,基本的pty界面分为三部分:
ptyget
:一个微小的低级程序(程序包中唯一的setuid程序),该程序分配一个新的伪tty并将其传递给您选择的程序ptyspawn
:另一个小程序,在伪tty下运行子进程,等待其退出并等待停止ptyio
:另一个只是稍大一点的程序,它来回移动数据
pty
现在已经拼出了旧的Ginsu刀ptybandage
,这是的同义词ptyget ptyio -t ptyspawn
;pty -d
,用于将网络程序附加到伪tty的拼写是ptyrun
,它是ptyget ptyio ptyspawn
; 的同义词。并且nobuf
是的同义词ptyget ptyio -r ptyspawn -23x
。我将会话管理功能拆分为一个单独的程序包。
那个单独的软件包就是“ sess”软件包。
顺便提一句,“ ptyget”是Berstein自己从未发布的“ redo”构建系统的早期版本,并且是该版本的少数已发布实例之一。 dependon
是明显的前兆redo-ifchange
。
ptybandage
ptybandage
人们通常在登录会话中想要的是。它的主要用例是使程序对它们的标准输入,输出或错误是否连接到终端很敏感,即使它们实际上位于外壳管道中,还是将其标准文件描述符重定向到文件。
它需要一个命令来运行(当然,它必须是一个适当的外部命令),并以某种方式运行它,使其认为其标准输入,输出和错误已附加到终端,并将这些终端连接到ptybandage
的原始标准输入,输出和错误。
它处理在作业控制外壳下运行的细微差别,确保终端STOP字符不仅停止,ptybandage
而且还停止连接到内部终端的程序的运行。
ptyrun
ptyrun
人们通常在TCP网络服务器中想要的。它的主要用例是远程执行环境,它们本身没有设置终端,运行的程序在没有终端的情况下无法按需运行。
它不希望在作业控制外壳下运行,并且如果正在运行的命令收到停止信号,则只需重启即可。
Dru Nelson同时发布了“ pty”第4版和“ ptyget”。
Paul Jarc发布了ptyget的固定版本,该版本尝试以操作系统实际上不再提供的原始版本处理特定于操作系统的伪终端设备ioctl。
nosh源软件包随附有workalike ptybandange
和ptyrun
脚本,它们使用Laurent Bercot的execline
工具和nosh软件包自己的伪终端管理命令。从nosh版本1.23开始,这些内容已预先包装在nosh-terminal-extras软件包中。(早期版本仅将其提供给从源代码构建的人。)
Jurjgen Oskam ptybandage
在AIX上使用将此处文档中的输入提供给显式打开的程序,并读取其控制终端以输入密码提示:
$ ptybandage dsmadmc << EOF> uit.txt 约斯卡姆 密码 查询会话 查询过程 退出 紧急行动
安迪·布拉德福德(Andy Bradford)使用ptyrun
daemontools和ucspi-tcp下的OpenBSD,使bgplgsh
交互式路由器控制程序可以通过网络访问,同时使其认为自己正在与终端通信:
#!/ bin / sh 执行2>&1 exec envuidgid rviews tcpserver -vDRHl0 0 23 ptyrun / usr / bin / bgplgsh
redo
。经常给出答案。bgplgsh
。8. OpenBSD手册页。expect
?
编译一个小的共享库:
echo "int isatty(int fd) { return 1; }" | gcc -O2 -fpic -shared -ldl -o isatty.so -xc -
然后告诉您的命令isatty(3)
动态加载此覆盖:
LD_PRELOAD=./isatty.so mycommand
这可能不适用于那里的每个命令,甚至可能以意外的方式破坏某些命令,但在大多数情况下可能会起作用。
DYLD_INSERT_LIBRARIES=./isatty.so DYLD_FORCE_FLAT_NAMESPACE=y mycommand
使用script(1)
怎么样?
例如:
script -q -c 'ls -G' out_file
将ls
输出保存到out_file
保留的颜色代码。
out_file
其颜色?
less -R
。不过,在这种情况下,我希望输出继续在管道中进行,最终最终在我的终端中结束。使用cat
进行说明,它是像script -q -c 'ls -G' /dev/null | cat
,这抑制了typescript
文件完全,只剩下程序的输出。
-
)作为script
输出文件,例如:script -q -c 'ls -G' -
基于@Amir的答案,下面是一个脚本,该脚本在运行时生成并包含该库:
#!/bin/bash
set -euo pipefail
function clean_up {
trap - EXIT # Restore default handler to avoid recursion
[[ -e "${isatty_so:-}" ]] && rm "$isatty_so"
}
# shellcheck disable=2154 ## err is referenced but not assigned
trap 'err=$?; clean_up; exit $err' EXIT HUP INT TERM
isatty_so=$(mktemp --tmpdir "$(basename "$0")".XXXXX.isatty.so)
echo "int isatty(int fd) { return 1; }" \
| gcc -O2 -fpic -shared -ldl -o "$isatty_so" -xc -
# Allow user to SH=/bin/zsh faketty mycommand
"${SH:-$SHELL}" -c 'eval $@' - LD_PRELOAD="$isatty_so" "$@"