我想知道一个进程是否正在运行,如果它正在运行,那么我想调用一个脚本或打印一些东西。我尝试了以下几种方法,但它给了我语法错误或命令未找到错误。
APP_ID = ps -eaf | grep -i `whoami` | grep -i <process_name> | grep -i java | awk '{print$2}'
if[''!= '${APP_ID}'] then
echo "Stopping instance $APP_ID"
我得到的结果如下:
test.sh: line 15: APP_ID: command not found
test.sh: line 17: if[!= ${APP_ID}]: command not found
Stopping instance
上面的脚本有什么问题?如果它有一些错误,那么为什么它会echo
在条件中打印if
?
下面的脚本也失败了test.sh: line 3: [ps: command not found
if [ps -eaf | grep -i `whoami` | grep -i <process_name> | grep -i java]; then
echo 'stop'
fi
答案1
你的语法有很多问题:
设置变量时删除“=”周围的空格
错误的:
APP_ID = value
正确的:
APP_ID=value
要运行程序并将其输出放入变量中,您需要
$(...)
(在 bash 中首选,在 sh 中不可用)或反引号`command`
(在 bash 和 sh 中支持)。 (请记住,分配变量时不需要引号,但在其他情况下它们很重要command "$(command)"
:)错误的:
APP_ID=command
正确的:
APP_ID=$(command)
使用“[”时在所有内容周围添加空格,并且在“]”后需要分号或换行符。这是因为“[”是 bash 内置命令,非内置命令也称为“test”(请参阅 参考资料
man test
),它就像其他命令一样,其参数用空格分隔:错误的:
if[x!= y] then echo hello world fi
正确的:
if [ x != y ]; then echo hello world; fi
当你想扩展变量时使用双引号,而不是单引号
错误的:
if [ '' != '${APP_ID}' ]; then
正确的:
if [ '' != "${APP_ID}" ]; then
同样对于上面的示例,您可以使用 -n (非空)而不是与空字符串进行比较
if [ -n "${APP_ID}" ]; then
对于 ps 示例,您不需要 grep 和 awk:
APP_ID=$(ps -C whoami --no-header --format 'pid')
这是修复后的脚本:
APP_ID=$(ps -C whoami --no-header --format 'pid')
if [ -n "${APP_ID}" ]; then
echo "Stopping instance $APP_ID"
fi
答案2
pgrep
使用and可以最简单地完成此操作pkill
:
if pgrep process_name 2>/dev/null; then
echo "Terminating process_name"
pkill process_name
fi
正如用户 @OrangeDog 在评论中指出的那样,理论上该 shell 代码可能无法终止进程process_name
如果进程在调用pgrep
和之间产生pkill
。在这种情况下,pgrep
将不会检测到该进程并且pkill
永远不会执行。这个问题有多大,我不知道。如果进程只是产生后声明,你能做什么?
做就是了
echo "terminating process_name (if it is running)"
pkill process_name
无论如何都要摆脱讨厌的竞争条件。
答案3
我不知道为什么,但上面的脚本没有给出任何语法问题,但尽管进程正在运行,但也没有给出进程 ID。
我最终将其更改如下并且有效 -
APP_ID=$(ps -ef | grep <app_name> | grep java | awk '{print $2}')
echo "Instance $APP_ID"
if [ -n "${APP_ID}" ]; then
echo "Stopping instance $APP_ID"
fi
再次感谢您的解释和指点。
@Peter,我会再次检查您发布的脚本,了解为什么它对我不起作用。
答案4
上面的命令也会捕获 grep 本身,因此,如果是 java 进程,该命令应该是
APP_ID=$(ps -ef | grep <app_name> | grep -v grep | awk '{print $2}')
echo "Instance $APP_ID"
if [ -n "${APP_ID}" ]; then
echo "Stopping instance $APP_ID"
kill $APP_ID (or kill -9 $APP_ID)
fi
希望这可以帮助。