在 xfce4-terminal 我执行:
if [[ $(pgrep -x xfce4-terminal) ]]; then echo "there are files" > test.txt; else echo "no files found" > test.txt; fi
其中写道there are files
。test.txt
如果我在一个 shell 脚本中执行同样的事情,当说 xfce4-terminal 仍然打开时调用,它会写:no files found
在test.txt
:
if [[ $(pgrep -x xfce4-terminal) ]]; then echo "there are files" > test.txt; else echo "no files found" > test.txt; fi
为什么会这样,我该怎么做才能修复(使 shell 脚本表现得像 shell)?
检查$(pgrep -x xfce4-terminal)
从终端:
echo $(pgrep -x xfce4-terminal) > toast.txt
# 8257
从外壳脚本:
echo $(pgrep -x xfce4-terminal) > toast.txt
# 8257
[[ ... ]]
扩展的测试构造首先出现在ksh
并随后被其他 shell 复制,包括bash
和zsh
.如果您尝试在简单的 POSIX shell 中使用它
/bin/sh
(例如,可能是因为您省略了 shebang - 请参阅哪个 shell 解释器运行没有 shebang 的脚本?)它将导致语法错误 - 并且if
无论如何都会导致条件失败测试的真实性。例如:但
但是,
[[ $(pgrep -x xfce4-terminal) ]]
测试是否存在名为 的正在运行的进程并不是最佳实践xfce4-terminal
,即使 shell 支持它也是如此。您可以直接使用退出状态,而不是使用命令替换$(...)
来捕获命令的标准输出pgrep
并测试其是否为非空字符串。来自:pgrep
man pgrep
所以
这将在任何类似 Bourne 的 shell(sh、ksh、bash、zsh)中工作。
在终端版本中,您有
[[ ]]
,它会评估其内容并在内容有效时返回退出状态 0,否则返回 1。如果只传递一个字符串,如果字符串的长度 > 0,则返回 0,否则返回 1。由于您的命令找到了某些内容,因此它返回长度 > 0 的字符串,并且[[ ]]
返回状态为 0 或“真”。if
在 shell 脚本中使用if
语句的返回值来确定是执行then
还是else
. 如果返回值为 0,则执行then
,否则跳至else
。但是,如果您选中
man pgrep
,它会为“一个或多个进程匹配条件”返回退出代码 1。因此,if
将其视为以非零错误代码退出,并跳至else
.为了解决这个问题,只需
[[ ]]
输入 shell 脚本版本。