shell 脚本中的超时并报告那些超时的输入

timeout in shell script and report those input with timeout

我想使用程序 Arlsumstat_64bit 对数千个输入文件进行分析。

Arlsumstat_64bit 读取输入文件 (.arp) 并写入结果文件 (sumstat.out)。 每个输入都会根据参数“0 1”
在结果文件 (sumstat.out) 上附加新行 因此,我写了一个 shell 脚本来执行同一个文件夹中的所有输入 (*.arp)。 但是,如果输入文件有错误,shell 脚本将被卡住,无法进行任何后续处理。因此,我找到了一个带有 "timeout" 的命令来处理我的问题。 我制作了一个 shell 脚本如下

#!/bin/bash

for sp in $(ls *.arp) ; 
do

echo "process start: $sp"


timeout 10 arlsumstat_64bit ${sp}.arp sumstat.out 1 0 

        rm -r ${sp}.res

        echo "process done: $sp"


done

但是,我仍然需要知道哪些输入文件失败了。 如何制作一个列表来告诉我哪些输入文件是 "timeout"?

以下代码应该适合您:

  #!/bin/bash
  for sp in $(ls *.arp) ; 
  do
  echo "process start: $sp"
  timeout 10 arlsumstat_64bit ${sp}.arp sumstat.out 1 0 
  if [ $? -eq 0 ]
  then
    echo "process done sucessfully: $sp"
  else
    echo "process failed: $sp"
  fi
  echo "Deleting ${sp}.res"
  rm -r ${sp}.res
  done

参见 timeout 命令的手册页 http://man7.org/linux/man-pages/man1/timeout.1.html

If the command times out, and --preserve-status is not set, then exit with status 124. Otherwise, exit with the status of COMMAND. If no signal is specified, send the TERM signal upon timeout. The TERM signal kills any process that does not block or catch that signal. It may be necessary to use the KILL (9) signal, since this signal cannot be caught, in which case the exit status is 128+9 rather than 124.

您应该找出程序 arlsumstat_64bit 可能的退出代码。我认为它应该在成功时以状态 0 退出。否则下面的脚本将无法运行。如果您需要区分超时和其他错误,则不应使用退出状态 124timeout 使用它来指示超时。因此,您可以根据需要检查命令的退出状态,以区分成功、错误或超时。

为了保持脚本简单,我假设您不需要区分超时和其他错误。

我在修改脚本的地方添加了一些评论以改进它或显示替代方案。

#!/bin/bash

# don't parse the output of ls
for sp in *.arp
do

    echo "process start: $sp"

    # instead of using "if timeout 10 arlsumstat_64bit ..." you could also run
    # timeout 10 arlsumstat_64bit...  and check the value of `$?` afterwards,
    # e.g. if you want to distinguish between error and timeout.

    # $sp will already contain .arp so ${sp}.arp is wrong
    # use quotes in case a file name contains spaces
    if timeout 10 arlsumstat_64bit "${sp}" sumstat.out 1 0 
    then
        echo "process done: $sp"
    else
        echo "processing failed or timeout: $sp"
    fi

    # If the result for foo.arp is foo.res, the .arp must be removed
    # If it is foo.arp.res, rm -r "${sp}.res" would be correct
    # use quotes
    rm -r "${sp%.arp}.res"

done