如何正确杀死bash中的进程

时间:2013-08-23 11:17:05

标签: linux bash kill

我使用以下脚本通过超时终止进程:

# $1 - name of program and its command line

#launch program and remember PID
eval "$1" &
PID=$!

echo "Program '"$1"' started, PID="$PID

i=1
while [ $i -le 300 ]
do
 ps -p $PID >> /dev/null
 if [ $? -ne 0 ]
  then
   wait $PID
   exit $? #success, return rc of program
  fi

 i=$(($i+1))
 echo "waiting 1 second..."
 sleep 1
done

#program does not want to exit itself, kill it
echo "killing program..."
kill $PID
exit 1 #failed

到目前为止,它工作得很好,但今天,我注意到htop中有一堆'悬挂'进程,所以我已经检查出来了,结果是$PID在这种情况下不是程序进程的ID,但脚本本身的ID,以及我检查的所有时间,程序的ID是$PID+1。现在,问题是,我是否正确地假设它始终是$PID+1并且我不会通过用kill $PID

之类的内容替换kill $PID $($PID+1)来杀死一些重要内容

编辑:$1可能有多个参数,例如./bzip2 -ds sample3.bz2 -k

5 个答案:

答案 0 :(得分:3)

只需进行以下更改即可解决问题:

自:

eval "$1" &

要:

eval "$1 &"

原因在this answer中解释。

答案 1 :(得分:2)

我刚开始用这个功能编写脚本。我打算称之为“超时”,但在我打开一个空白文件之前,我检查是否已经有一个同名的命令。有... ...

timeout

修改

如果您特别需要“1”作为失败的返回值......

timeout 1 nano -w; `if [[ $? == 124 ]] ; then exit 1 ; fi ; exit $?`

答案 2 :(得分:1)

普通

有什么问题
( eval "$1" ) &
sleep 300
kill %1

答案 3 :(得分:1)

你是后台eval,而不是它运行的命令,而eval是一个内置的shell,所以你要求一个新的shell;这就是为什么(我认为)$!是当前shell的PID。

一个简单的解决方案是避免使用eval(为此以及通常对安全性的担忧)。

$1 "$@" &
PID=$!

是的,这不允许您将任意bash命令行(管道,&& list等)传递给您的脚本,但您的用例可能不需要支持此类泛化。你通常会传递什么命令?

答案 4 :(得分:0)

此外,这里有一些重构你的代码,也许你会从中学到一些东西:

#launch program and remember PID
eval "$1" &
PID=$!

echo "Program '$1' started, PID=$PID" # you can safely use single quotes inside double quotes, your variables are going to work in  " " as well!

i=1
while (( i <= 300 )) # use (( )) for math operations!
do
    ps -p "$PID" >> /dev/null # it is a good rule to quote every variable, even if you're pretty sure that it doesn't contain spaces
    if [[ $? != 0 ]]; then # Try to use [[ ]] instead of [. It is modern bash syntax
        wait "$PID"
        exit "$?" #success, return rc of program
    fi
    ((i++))
    echo "waiting 1 second..."
    sleep 1
done

#program does not want to exit itself, kill it
echo "killing program..."
kill "$PID"
exit 1 #failed