在Bash脚本中,我想要执行以下操作(伪代码):
if [ a process exists with $PID ]; then
kill $PID
fi
条件语句的适当表达式是什么?
在Bash脚本中,我想要执行以下操作(伪代码):
if [ a process exists with $PID ]; then
kill $PID
fi
条件语句的适当表达式是什么?
我 从这里学到并点赞了 @FDS 的答案, 因为它很好也是正确的。但是,这里有个我认为更容易阅读和理解的表格。
说明:
"$?"
部分表示“前一个命令的退出或返回代码”。ps --pid "$pid"
命令返回退出代码 0
,如果指定的 PID("$pid"
)正在运行,则返回其他数字。> /dev/null
可以丢弃所有打印到 stdout
的输出,因为我们不想看到它们。相反,我们只需要来自 ps --pid "$pid"
命令的退出代码("$?"
)来查看该 PID 是否正在运行。更具体地说,使用 > /dev/null
将 stdout
输出重定向到虚拟文件 /dev/null
中,其目的是丢弃所有传入输入。pid=1234
ps --pid "$pid" > /dev/null
if [ "$?" -eq 0 ]; then
echo "PID $pid exists and is running."
fi
运行 shellcheck path/to/this_script.sh
告诉我应该按照 @FDS 的方式来避免冗余。在这里查看 shellcheck
输出:
eRCaGuy_hello_world/bash$ shellcheck check_if_pid_exists.sh
In check_if_pid_exists.sh line 46:
if [ "$?" -eq 0 ]; then
^--^ SC2181: Check exit code directly with e.g. 'if mycmd;', not indirectly with $?.
For more information:
https://www.shellcheck.net/wiki/SC2181 -- Check exit code directly with e.g...
特别注意这部分:
SC2181:直接使用 '
if mycmd;
' 检查退出代码,而不是间接使用$?
。
在此处查看此错误代码的完整描述:https://github.com/koalaman/shellcheck/wiki/SC2181。
shellcheck
建议使用以下形式:pid=1234
if ps --pid "$pid" > /dev/null; then
echo "PID $pid exists and is running."
fi
如果你想调整成那种方式,就去试试吧。但是,如果你认为我的方式更易于阅读和理解,像我一样,那么你可以通过在那行上面添加# shellcheck disable=SC2181
来选择性地禁用shellcheck
警告,就像这样:
ps --pid "$pid" >/dev/null
# shellcheck disable=SC2181
if [ "$?" -eq 0 ]; then
echo "PID $pid exists and is running."
else
echo "PID $pid does NOT exist."
fi
然而,这里的关键是永远不要在正在检查的命令(在本例中为ps
)和使用"$?"
检查错误代码之间插入任何命令,甚至不是echo
或print
语句,否则检查错误代码将意外地检查最新命令的错误代码,例如插入的echo
或print
语句,而不是感兴趣的命令(在我们的例子中为ps
)!
这就是为什么shellcheck
建议他们所做的事情的主要原因:他们想确保您检查了正确命令的错误代码。
除此之外,这只是一个吹毛求疵的基于观点的讨论,相当于C语言中关于如何检查NULL
(空指针)值的争论:
// The way preferred by pedantic people who don't want to "be redundant" with
// an "unnecessary" `== NULL` check:
if (!some_ptr)
{
printf("ERROR: null ptr.\n");
return;
}
// Versus the more-readable and understandable way which I prefer to use
// whenever my peers will approve it without a fight or long argument
if (some_ptr == NULL) // in C
// if (some_ptr == nullptr) // in C++
{
printf("ERROR: null ptr.\n");
return;
}
// Note: I just want to get my code merged and move on with life, so if they
// won't easily approve my preferred version above, I'll switch to the other,
// more-pedantic version of code to try to get a quick approval so I can be
// more productive.
// There are few things more discouraging than being blocked over
// silly "pedantry" when your code is correct, bug-free, well-written, and does
// what it says it does.
因此,就像在C语言中选择检查NULL
值(空指针)的方式一样,检查bash中的错误代码/返回代码的方式也纯粹是品味问题。目前,我更喜欢上面标记为“我的最终和首选答案”的版本。
check_if_pid_exists.sh 来自我的eRCaGuy_hello_world仓库:
#!/usr/bin/env bash
pid=1234
if [ "$#" -gt 0 ]; then
# At least 1 argument was passed in, so assume it is the PID
pid="$1"
fi
# Try to print the process (`ps`) information for this PID. Send it to
# /dev/null, however, so we don't actually have to look at it. We just want
# the return code, `$?`, which will be 0 if the process exists and some other
# number if not.
ps --pid "$pid" > /dev/null
# shellcheck disable=SC2181
if [ "$?" -eq 0 ]; then
echo "PID $pid exists and is running."
else
echo "PID $pid does NOT exist."
fi
示例运行调用和输出:
eRCaGuy_hello_world/bash$ ./check_if_pid_exists.sh 28876
PID 28876 exists and is running.
eRCaGuy_hello_world/bash$ ./check_if_pid_exists.sh
PID 1234 does NOT exist.
eRCaGuy_hello_world/bash$ ./check_if_pid_exists.sh 5678
PID 5678 does NOT exist.
您可以通过先运行ps aux
并选择要传递给我的脚本的PID来找到有效的PID(进程ID)。