检查进程并杀死正在运行的进程

检查进程并杀死正在运行的进程

我想知道一个进程是否正在运行,如果它正在运行,那么我想调用一个脚本或打印一些东西。我尝试了以下几种方法,但它给了我语法错误或命令未找到错误。

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

希望这可以帮助。

相关内容