Answers:
从man bash下条件表达式:
-t fd
True if file descriptor fd is open and refers to a terminal.
假设fd 1是标准配置,if [ -t 1 ]; then应该为您工作。《高级Shell脚本指南》声称-t使用这种方式将进行故障转移ssh,因此测试(使用stdin而非stdout)应为:
if [[ -t 0 || -p /dev/stdin ]]
-p测试文件是否存在并且是命名管道。 但是,我会从经验上注意到这对我来说是不正确的:-p /dev/stdin对于普通终端和ssh会话均失败,而if [ -t 0 ](或-t 1)在两种情况下均有效(另请参见下面关于高级Shell脚本指南那部分内容的Gilles评论)。
如果主要问题是特定的上下文,您希望从中调用脚本以适合该上下文的方式运行,则可以回避所有这些技术知识,并使用包装器和自定义变量为自己省事:
!#/bin/bash
export SPECIAL_CONTEXT=1
/path/to/real/script.sh
调用此名称live_script.sh或其他名称,然后双击该名称。您当然可以使用命令行参数完成相同的操作,但是仍然需要使用包装器来指向并单击GUI文件浏览器。
||中[ … ]这样呢?如果使用,[[ … ]]则可以,但是通常||使用来分隔命令,并且由于缺少最后[ -t 0一个,因此是不正确的调用。通常也没有命令。我同意测试终端;那可能就是这样做的方式。这只是我所关心的语法。[]-p
||在所需的最终]参数之前出现[。
PS1判断外壳是否交互式的可靠测试。“如果脚本需要测试它是否在交互式外壳中运行”也令人困惑:应该是某些代码是否需要测试—脚本通常不在交互式外壳中运行(但可以,如果是源代码则可以) 。测试iin $-是测试外壳是否交互式的正确方法。测试-t 0或是-t 2判断脚本是否在终端中运行的正确方法,这不同于交互方式。
尽管Goldilocks的回答在典型情况下可能是正确的,但似乎确实存在一些极端情况。在我自己的情况下,我的xserver配置为从其启动,tty1并且从不离开该tty。如果Xorg stdout是一个TTY,那么默认情况下,客户端似乎会将TTY链接到其文件描述符。
这是我解决问题的方法:
#!/bin/bash
isxclient=$( readlink /dev/fd/2 | grep -q 'tty' && [[ -n $DISPLAY ]] ; echo $? )
if [[ ! -t 2 || $isxclient == "0" ]]; then
notify-send "Script wasn't started from an interactive shell"
else
echo "Script was started from an interactive shell"
fi
我还没有测试它是否可以在更标准的X配置上工作,我也非常怀疑这是唯一的优势。如果有人找到更通用的解决方案,请回来告诉我们。
另一个,使用bash选项设置内部变量$-。
来自.bashrc,
# If not running interactively, don't do anything
case $- in
*i*) ;;
*) return;;
esac
cmd | sh -i | cmd。