我在做標準的重定向:我該如何欺騙程序stdin是終端(而不是重定向文件)?
$ cat file.txt | /usr/bin/program
但程序的行爲不同,如果我直接在終端上運行它,並複製粘貼輸入。 當輸入是終端時,它顯示進度條。無論如何,我想要有進度條。
總之,我該如何「欺騙」輸入來自終端並且沒有被重定向到文件的程序呢?
我在做標準的重定向:我該如何欺騙程序stdin是終端(而不是重定向文件)?
$ cat file.txt | /usr/bin/program
但程序的行爲不同,如果我直接在終端上運行它,並複製粘貼輸入。 當輸入是終端時,它顯示進度條。無論如何,我想要有進度條。
總之,我該如何「欺騙」輸入來自終端並且沒有被重定向到文件的程序呢?
您需要使用僞tty才能獲得所需的效果。 'man pty'會告訴你更多關於它的信息。
我假定程序會調用glibc函數isatty()
來檢查stdin/stdout是否是終端。對於在終端上使用彩色輸出的程序或ANSI終端的其他功能(如光標定位或行擦除/重繪),這是很常見的。
您可以使用LD_PRELOAD環境變量欺騙程序。 LD_PRELOAD由ELF鏈接器處理,並告訴動態庫應該在之前被加載。使用此功能可以重寫庫函數,在您的情況下glibc函數isatty()
。
這裏談到的例子:
libisatty.c
/**
* Overrides the glibc function. Will always return true.
*
* Note: Although this should be ok for most applications it can
* lead to unwanted side effects. It depends on the question
* why the programm calls isatty()
*/
int isatty(int param) {
return 1;
}
生成文件
# Make the shared Library
lib: libisatty.c
gcc -shared -Wl,-soname,libisatty.so.1 -o libisatty.so.1.0 libisatty.c
ln -s libisatty.so.1.0 libisatty.so.1
ln -s libisatty.so.1 libisatty.so
執行命令
make lib
它應該很好,我已經在Ubuntu12.04 AMD 64上測試過它。
現在是時候測試庫了。 :)我已經使用命令ls --color=auto
進行測試。 ls
調用isatty()
來決定是否着色它的輸出。如果輸出重定向到文件或管道,則不會着色。您可以測試這一點很容易使用下面的命令:
ls --color=auto # should give you colorized output
ls --color=auto | cat # will give you monochrome output
現在,我們將嘗試第二個命令再次使用LD_PRELOAD環境VAR:
LD_PRELOAD=libisatty.so ls --color=auto | cat
你應該看到彩色輸出。
這可能是最簡單的使用expect
程序;它爲你做了大部分必要的工作。
必要的工作很瑣碎。它涉及使用僞ttys,這是看終端程序的設備。如果你打算推出自己的,那麼POSIX系統調用,你需要了解的是:
的posix_openpt()
接口是相對較新的(第6版,與第4版第2版列出的其他功能相比)。如果你的系統沒有posix_openpt()
,你需要自己找一本Unix書籍(Stevens或Rochkind,可能)來找出如何打開pty的主控端,或者仔細閱讀你的系統手冊。但是,上述鏈接中posix_openpt()
的基本原理也可能有所幫助 - 它也有使用其他功能的指導原則。 Linux有posix_openpt()
; Mac OS X也是如此,並且通常推斷BSD系統。
書籍:
理查德·史蒂文斯,斯蒂芬一拉戈 Advanced Programming in the Unix Environment, 3rd Edn
馬克ĴRochkind Advanced Unix Programming, 2nd Edn
'在/ usr/bin中/程序file.txt'沒有按不工作? – 2013-02-25 01:39:37
或'/ usr/bin/program
squiguy
2013-02-25 01:42:17
傳統的方法是使用[expect](http://expect.sourceforge.net/)。 – 2013-02-25 03:04:50