0

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

# $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 都是$PID+1. 现在,问题是,我的假设是否正确,它将永远存在$PID+1,而且我不会通过替换为类似的东西来杀死重要的kill $PID东西kill $PID $($PID+1)

编辑:$1可能有几个要求,比如./bzip2 -ds sample3.bz2 -k

4

5 回答 5

3

您可以通过以下更改简单地解决问题:

从:

eval "$1" &

到:

eval "$1 &"

这个答案解释了原因。

于 2013-08-23T12:38:42.723 回答
2

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

超时

编辑

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

timeout 1 nano -w; `if [[ $? == 124 ]] ; then exit 1 ; fi ; exit $?`
于 2013-08-23T12:17:30.317 回答
1

素颜有什么不好

( eval "$1" ) &
sleep 300
kill %1
于 2013-08-23T11:27:29.383 回答
1

您正在后台eval运行,而不是它运行的命令,并且eval是内置的外壳,因此您正在分叉一个新外壳;这就是为什么(我认为)$!是当前 shell 的 PID。

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

$1 "$@" &
PID=$!

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

于 2013-08-23T12:24:07.073 回答
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
于 2013-08-23T13:27:56.317 回答