在 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
从 shell 脚本:
echo $(pgrep -x xfce4-terminal) > toast.txt
# 8257
答案1
扩展的测试构造[[ ... ]]
首先出现在ksh
,随后被包括bash
和在内的其他shell复制zsh
。
如果你尝试在一个简单的 POSIX shell 中使用它/bin/sh
(可能是因为你省略了 shebang,例如 - 请参阅哪个 shell 解释器可以运行没有 shebang 的脚本?)将导致语法错误 -if
无论测试是否真实,都将导致条件失败。例如:
$ bash -c 'if [[ 1 -eq 1 ]]; then echo "equal"; else echo "not equal"; fi'
equal
但
$ sh -c 'if [[ 1 -eq 1 ]]; then echo "equal"; else echo "not equal"; fi'
sh: 1: [[: not found
not equal
然而,[[ $(pgrep -x xfce4-terminal) ]]
并不是测试是否存在名为 的正在运行的进程的最佳实践xfce4-terminal
,即使 shell 支持它。除了使用命令替换$(...)
来捕获命令的标准输出pgrep
并测试它是否为非空字符串之外,您还可以使用退出状态pgrep
直接。来自man pgrep
:
EXIT STATUS
0 One or more processes matched the criteria. For pkill the
process must also have been successfully signalled.
1 No processes matched or none of them could be signalled.
2 Syntax error in the command line.
3 Fatal error: out of memory etc.
所以
if pgrep -x xfce4-terminal >/dev/null; then
echo "there are files" > test.txt
else
echo "no files found" > test.txt
fi
它可以在任何类似 Bourne 的 shell (sh、ksh、bash、zsh) 中运行。
答案2
在终端版本中,您有[[ ]]
,它会评估其内容,如果内容有效,则返回退出状态 0,否则返回 1。如果仅传递一个字符串,则如果字符串的长度 > 0,则返回 0,否则返回 1。由于您的命令发现了某些内容,它会返回长度 > 0 的字符串,并且返回[[ ]]
状态 0 或“true”。
if
在shell脚本中,使用语句的返回值if
来决定是否执行then
或else
。如果返回值为0,则执行then
,否则跳至else
。
但是,如果您检查man pgrep
,它会返回退出代码 1,表示“一个或多个进程符合条件。”因此,if
会将其视为以非零错误代码退出,并跳至else
。
为了修复这个问题,只需加入[[ ]]
shell 脚本版本即可。