2012-02-18 90 views

回答

21

您應該能夠使用-t測試開關告訴如果輸出流是tty S,或不:

if [ -t 1 ] ; then 
    echo stdout is a terminal 
else 
    echo stdout is not a terminal 
fi 

使用-t 0stdin

對於stderr使用-t 2

+0

它按我的意願工作!非常感謝 – Sigmun 2012-02-18 13:28:58

25

從技術上講,無法判斷標準輸入/標準輸出/標準錯誤是否「重定向」,因爲您不知道什麼是調用腳本。如果它沒有從另一個shell調用,那麼就沒有「重定向」的概念。

你所要做的就是輸入/輸出/ err文件描述符是什麼類型(terminal,fifo,pipe,device,file等)。通常你只是想檢測你的輸出是否進入某個用戶的屏幕,或者是否要進入另一個進程。在這種情況下,根據Mat的答案使用[ -t 1 ]

如果您想了解您的進程已重定向到哪裏/什麼,請檢查符號鏈接/proc/$$/fd/1/proc/$$/fd/2的目標。

請注意,有人可能會將您的流程的輸出連接到與./myscript.sh > /dev/pts/1234不同的終端。然後它會被「重定向」,但stdout仍然是一個終端。

例子:

$ ls -l /proc/$$/fd/1 > results 
$ bash -c 'ls -l /proc/$$/fd/1 >>results' > /dev/null 
$ bash -c 'ls -l /proc/$$/fd/1 >>results' |cat 
$ bash -c 'ls -l /proc/$$/fd/1 >>results' > /dev/pts/0 
$ cat results 
lrwx------ 1 je4d je4d 64 2012-02-17 21:09 /proc/2463/fd/1 -> /dev/pts/11 
l-wx------ 1 je4d je4d 64 2012-02-18 13:17 /proc/8302/fd/1 -> /dev/null 
l-wx------ 1 je4d je4d 64 2012-02-18 13:17 /proc/8304/fd/1 -> pipe:[222798] 
l-wx------ 1 je4d je4d 64 2012-02-18 13:17 /proc/8307/fd/1 -> /dev/pts/0 

[ -t 1 ]將是那些第一和第四真。

+2

這是一個豐富的答案,可以讓我理解一些bash的東西。謝謝 ! – Sigmun 2012-02-18 13:33:19

+0

Thx!我做了一個命令行測試,但這並不令我意外。這個命令:'(lsof -p $$; ls -l/proc/$$/fd; [-t 1] || echo -n NOT \; echo TERM:$$; ps --forest -s $$; )| cat -'爲fd 1打印'/ dev/pts/1',但打印'NOT TERM'。所以[tag:bash]知道它被重定向('(...)'在一個子[tag:bash]中運行),但$$仍然是父[tag:bash]的PID。 – TrueY 2015-07-23 18:19:32

+0

是的,這正是$$所做的,subhells不會影響它。這就是爲什麼我用bash -c'...'代替。 – je4d 2015-08-08 11:35:35

相關問題