在bash中检查isatty

在bash中检查isatty,bash,shell,Bash,Shell,我希望我的shell检测是否有人类行为,然后显示提示 因此,假设文件名为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 #

我希望我的shell检测是否有人类行为,然后显示提示

因此,假设文件名为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

帮助测试


您可以使用
/usr/bin/tty
程序:

if tty -s
then
    # ...
fi

我承认我不确定它的可移植性有多好,但它至少是GNU coreutils的一部分。

要详细说明,我会尝试

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

    ....
 fi
我希望这能有所帮助。

请注意,在bash脚本中(请参阅
manbash
中的
testexpr
条目),不必使用beefy
&&
|
shell操作符来组合
[/code>命令的两次单独运行,因为
[
命令有自己的内置和
-a
和或
-o
操作符,允许您将几个简单的测试组合成一个结果

因此,下面是如何实现您要求的测试—如果输入或输出已从TTY重定向,则切换到批处理模式—使用单个调用
[

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

谢谢,你的答案是正确的,但是下一个答案更清晰。@Daniel YC Lin,所以已经重新安排了答案,所以我不确定你指的是什么答案,这个答案后面没有任何内容。你的示例适合标准输入法,对于标准输出法,我们可以使用
if[-t1]
。最好的答案是
if[-t0]&&[-t1]
谢谢分享。这似乎是个好主意。有时少就是多,有时少就是少。那么……这是我不知道的shell脚本中的一个新范例,还是你的个人观点?祝大家好运。作为附录,由于问题明确提到Bash,这是首选方式:
[-t0]
(和/或1,取决于您是否要检查stdin和/或stdout是否连接到终端)因为
[[]]
是一个Bash内置命令,而
[]
生成一个外部进程。@DanielYCLin,
[
(又称
测试
)具有内置的“和”-
-a
Shellcheck说
[a]&[b]
[a-ab]
更具可移植性(如果您对具体内容感兴趣,下面是它给出的信息:
SC2166:首选[p]&[q],因为[p-aq]没有很好的定义。
)请注意,-a和-o是不能保证在所有shell或
test
实现中都存在或工作相同的扩展。即使是GNU
test
手册页也警告不要使用它们。@bacondropped@ʇsәɹoɈ-因为问题是关于bash脚本的,管理文档是
manbash
而不是
mantest
,一个nd
-a
-o
都有很好的说明和完整的描述。不过,您的评论对任何回答这个问题但为非bash shell编写并且没有意识到区别的人来说都是有用的!我编辑了我的答案,以更清楚地说明它是特定于bash的,并参考bash ma的相应部分n页。根据,
tty
可能不支持
-s
选项。因此,请使用
[-tn]
,或将输出重定向到
/dev/null
。如果要检查stdout,而不是stdin,请执行
tty
if [ -t 0 -a -t 1 ]
then
    echo Interactive mode
else
    echo Batch mode
fi