如何超时我在BASH中捕获输出的进程?

时间:2015-02-26 10:04:32

标签: bash

我有一个脚本:

timeout 5 ./cl_launcher -p 0 -d 0 -f ${file} > ./ResultsOpt/$(basename "$file" .c)_test.txt

进程./cl_launcher输出我想要捕获的文件的测试结果。但是,偶尔cl_launcher不会终止,所以我想确保在这种情况下它会被杀死。当前脚本没有超时。有什么想法吗?

以下是完整的脚本:

1 #!/bin/bash
2 #Called with a directory of .c programs as an arg
3 export LC_ALL=C
4 
5 #Get DIR and OPT 
6 DIR="$1"
7 echo "with or without optimizations?"
8 read OPT
9 COUNTER=0
10 
11   if [ "$OPT" = "with" ]; then
12     #Get kernel results and store
13     mkdir ./$(basename "$DIR")_ResultsOpt/
14     for file in ${DIR}*.c; do
15       timeout 5 ./cl_launcher -p 0 -d 0 -f ${file} > ./$(basename "$DIR")_ResultsOpt/$(basename "$file" .c)_test.txt
16     COUNTER=$((COUNTER + 1))
17     echo "Process ${COUNTER} finished at `date +%s`"
18     done
19 
20   elif [ "$OPT" = "without" ]; then
21     #Get kernel results and store
22     mkdir ./$(basename "$DIR")_ResultsNoOpt/
23     for file in ${DIR}*.c; do
24       timeout 5 ./cl_launcher -p 0 -d 0 -f ${file} ---disable_opts > ./$(basename "$DIR")_ResultsNoOpt/$(basename "$file" .c)_test.txt
25     COUNTER=$((COUNTER + 1))
26     echo "Process ${COUNTER} finished at `date +%s`"
27     done
28 
29   else
30     echo "Enter with or without"
31   fi
32 
33 echo "finished"

1 个答案:

答案 0 :(得分:2)

如果timeout无法正常工作,那么在有限的时间内杀死该过程似乎也可能无法正常工作。我的推测是timeout命令发送信号2,目标进程以某种方式忽略或躲避,因此你需要尝试不同的信号。也许尝试像

这样的东西
#!/bin/bash
#Called with a directory of .c programs as an arg
export LC_ALL=C

#Get DIR and OPT 
DIR="$1"

while true; do
    read -p "With or without optimizations? " OPT
    case $OPT in
      with)  opt=""; res="ResultsOpt";  break;;
      without) opt="--disable-opts"; res="ResultsNoNopt"; break;;
      *) echo "Enter with or without";;
    esac
done

COUNTER=0

#Get kernel results and store
mkdir ./$(basename "$DIR")_"$res"/
for file in ${DIR}*.c; do
      ./cl_launcher -p 0 -d 0 -f ${file} > ./$(basename "$DIR")_"$res"/$(basename "$file" .c)_test.txt &
      pid=$!
      for sig in 0 0 0 0 2 0 15 0 9; do
          sleep 1
          kill -0 "$pid" || break   # Still there?  Hello?
          case $sig in 0) ;; *) kill -$sig "$pid" ;; esac
      done
      wait "$pid"
      COUNTER=$((COUNTER + 1))
      echo "Process ${COUNTER} finished at `date +%s`"
done
#echo "finished"

还要注意脚本是如何重构的,以避免重复代码。我还会将优化选项委托给一个选项,而不是需要交互式输入。