2012-04-05 50 views
11

我想让我的shell检测人类行为,然后显示提示。在bash中检查isatty

因此,假设文件名是test.bash

#!/bin/bash 
if [ "x" != "${PS1:-x}" ] ;then 
read -p "remove test.log Yes/No" x 
[ "$x" = "n" ] && exit 1 
fi 
rm -f test.log 

但是,我发现,如果我没有设置PS1它不能正常工作。有更好的方法吗?

我的测试方法:

./test.bash     # human interactive 
./test.bash > /tmp/test.log # stdout in batch mode 
ls | ./test.bash    # stdin in batch mode 

回答

28

阐述,我会尝试

if [ -t 0 ] ; then 
    # this shell has a std-input, so we're not in batch mode 
    ..... 
else 
    # we're in batch mode 

    .... 
fi 

我希望这有助于。

+3

您的示例适用于** stdin **的情况,对于** stdout **,我们可以使用'if [-t 1]'。如果[-t 0] && [-t 1]' – 2012-08-21 01:49:36

+1

。这似乎是一个好主意。有时少就是更多,有时少就是少。所以......这是一个我不知道的shell脚本的新范例,还是您的个人意见?祝你们好运。 – 2012-08-21 01:55:51

+0

感谢您的分享,最好的答案是 – shellter 2012-08-21 02:52:31

7

help test

-t FD   True if FD is opened on a terminal. 
+0

谢谢,你的回答是正确的,但下一个答案更清晰。 – 2012-08-21 01:44:04

5

你可以利用/usr/bin/tty方案:

if tty -s 
then 
    # ... 
fi 

我承认我不确定它是如何移植的,但它至少是GNU coreutils的一部分。

+0

根据[this](http://pubs.opengroup.org/onlinepubs/9699919799/utilities/tty.html),'tty'可能不支持'-s'选项。所以要么使用'[-t N]',要么将输出重定向到'/ dev/null'。 – 2016-11-16 23:25:49

+0

而且,如果你想检查stdout,而不是stdin,请执行'tty 2016-11-16 23:27:04

2

请注意,这是没有必要使用仡&&||外壳运营两个独立的运行结合[命令,因为[命令有其自己的内置-a-o运算符让你将几个简单的测试组合成一个结果。

所以,这里是你如何可以实现你要的测试 - 采用[一个调用 - 在这里你翻转到如果要么输入输出已经从TTY重定向离开批处理模式:

if [ -t 0 -a -t 1 ] 
then 
    echo Interactive mode 
else 
    echo Batch mode 
fi 
+0

Shellcheck说'[a] && [b]'比'[a -ab]'更便于携带,不过。 – bacondropped 2016-09-03 20:25:44

+0

(如果你对细节感兴趣,下面给出它的信息:'SC2166:由于[p -a q]没有很好的定义,所以首选[p] && [q] – bacondropped 2016-09-03 20:31:53