Shell

如何欺騙命令使其認為其輸出將發送到終端

  • August 4, 2021

給定一個在其輸出到終端時改變其行為的命令(例如產生彩色輸出),該輸出如何在管道中重定向,同時保留改變的行為?必須有一個實用程序,我不知道。

一些命令,如grep --color=always,具有強制執行行為的選項標誌,但問題是如何解決僅依賴於測試其輸出文件描述符的程序。

如果重要的話,我的 shell 是bash在 Linux 上的。

您可能會通過使用unbuffer.

unbuffer是一個tcl/expect腳本。如果需要,請查看原始碼。還要注意 man 中的 CAVEATS 部分。

另請注意,它不執行別名,例如:

alias ls='ls --color=auto'

除非像 Stéphane Chazelas 所說的那樣添加一個技巧:

如果您執行 a alias unbuffer='unbuffer '(注意尾隨空格),則別名將在unbuffer.

工具集的歷史

您不是第一個需要這種工具的人。30 年來,人們一直想要這樣的工具。它們也已經存在了差不多這麼長時間。

最早用於此類事情的工具是 Daniel J. Bernstein 的“pty”包,Rich Salz 將其描述為“Ginsu 刀”,Bernstein 在 1990 年代之交回信以在 nethack 上作弊(原文如此!)。“pty”包的第 4 版於 1992 年發布至comp.sources.unix(第 25 卷第 127 至 135 期)。它仍然可以在全球資訊網上找到。Paul Vixie 當時是這樣描述的:

我能說什麼?它切片、切丁、洗碗、遛狗。它“正常工作”,這意味著如果您按照說明進行操作,您將獲得一個工作包,而無需拉扯頭髮或咬牙切齒或進行其他標準的移植活動。

伯恩斯坦後來在 1999 年 4 月 7 日或之前的某個時候更新了這個,用一個“ptyget”包,他宣布:

我已經組合了一個新的偽 tty 分配器 ptyget。Alpha 版本位於ftp://koobera.math.uic.edu/pub/software/ptyget-0.50.tar.gz. 有一個 ptyget 郵件列表;要加入,請向 發送空消息 djb-ptyget-requ...@koobera.math.uic.edu。我從頭設計了 ptyget 的界面。它比 pty 模組化得多;基本的 pty 介面現在已分為三部分:

  • ptyget: 一個很小的低級程序——包中唯一的 setuid 程序——它分配一個新的偽 tty 並將其傳遞給您選擇的程序
  • ptyspawn:另一個在偽tty下執行子程序的小程序,等待它退出並觀察停止
  • ptyio:另一個稍微大一點的程序,用於來回移動數據

舊的 Ginsu 刀pty現在拼寫ptybandage為 ; 的同義詞ptyget ptyio -t ptyspawn; pty -d,用於將網路程序附加到偽 tty,現在拼寫為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 網路伺服器。它的主要案例是遠端執行環境,它們本身沒有設置終端,執行的程序在沒有終端時不能按預期執行。

它不希望在作業控制外殼下執行,並且如果正在執行的命令收到停止信號,它就會重新啟動。

可用的工具集

Dru Nelson 發布了“pty”版本 4 和“ptyget”。

Paul Jarc 發布了一個固定版本的 ptyget,它試圖處理作業系統實際上不再提供的原始作業系統特定的偽終端設備 ioctl。

nosh 原始碼包帶有 workalikeptybandangeptyrun腳本,它們使用 Laurent Bercot 的execline工具和 nosh 包自己的偽終端管理命令。從 nosh 版本 1.23 開始,這些已預先打包在 nosh-terminal-extras 包中。(早期版本僅將它們提供給從原始碼建構的人。)

幾個範例使用

Jurjgen Oskamptybandage在 AIX上使用將來自 here 文件的輸入提供給一個程序,該程序顯式打開並讀取其控制終端以獲取密碼提示:

$ ptybandage dsmadmc <<EOF >uit.txt
約斯卡姆
密碼
查詢會話
查詢流程
辭職
EOF

Andy Bradfordptyrun在 OpenBSD 上使用daemontools 和 ucspi-tcp 使bgplgsh互動式路由器控製程序可以通過網路訪問,同時讓它認為它正在與終端對話:

#!/bin/sh
執行 2>&1
exec enuidgid rviews tcpserver -vDRHl0 0 23 ptyrun /usr/bin/bgplgsh

進一步閱讀

引用自:https://unix.stackexchange.com/questions/249723