【问题标题】:timeout in shell script and report those input with timeout在 shell 脚本中超时并报告这些输入超时
【发布时间】:2019-03-20 09:30:31
【问题描述】:

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

Arlsumstat_64bit 读取输入文件 (.arp) 并写入结果文件 (sumstat.out)。 每个输入都将根据参数“0 1”在结果文件 (sumstat.out) 上附加新行
因此,我编写了一个 shell 脚本来执行同一文件夹中的所有输入 (*.arp)。 但是,如果输入文件包含错误,shell 脚本将被卡住而没有任何后续处理。因此,我找到了一个带有“超时”的命令来处理我的问题。 我做了一个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

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

【问题讨论】:

  • 建议改进:使用for sp in *.arp 而不是使用ls 的输出。 $sp 将包括.arp,所以它可能应该是arlsumstat_64bit ${sp} sumstat.out 1 0rm -r ${sp%.arp}.res

标签: linux shell timeout


【解决方案1】:

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

如果命令超时,并且 --preserve-status 未设置,则退出 状态为 124。否则,以 COMMAND 状态退出。如果不 信号被指定,超时时发送 TERM 信号。术语 信号杀死任何不阻塞或捕获该信号的进程。 可能需要使用 KILL (9) 信号,因为该信号 无法被捕获,此时退出状态为 128+9 而不是 124.

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

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

我添加了一些 cmets,我在其中修改了您的脚本以改进它或显示替代方案。

#!/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

【讨论】:

    【解决方案2】:

    下面的代码应该适合你:

      #!/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
    

    【讨论】:

    • 应该是 if [ $? -eq 0 ] 。我建议将for 循环体中的行缩进以使脚本更具可读性。
    猜你喜欢
    • 2021-02-03
    • 1970-01-01
    • 2014-03-23
    • 1970-01-01
    • 1970-01-01
    • 2017-03-18
    • 2015-03-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多