2012-02-18 129 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