如果任何命令运行时间太长而无法运行脚本

时间:2017-04-21 02:43:50

标签: bash

我有一个名为A的应用程序,它接收输入n并在返回答案之前运行一段时间。

我希望使用以下简单的bash脚本执行A以增加n的大小:

#!/bin/sh

time ./A 10
time ./A 20
time ./A 30
.
.
.

但是我也需要一些非常重要的东西。如果time调用执行时间太长,因为输入很大,那么我需要整个bash脚本停止运行。

有没有一种简单的方法可以做到这一点?

3 个答案:

答案 0 :(得分:3)

以下可行:

#! /bin/bash                                                                                   

timeout 2 time sleep 1                                                                         
if [[ $? == 124 ]]                                                                             
then                                                                                           
    exit;                                                                                      
fi                                                                                             

timeout 2 time sleep 3                                                                         
if [[ $? == 124 ]]                                                                             
then                                                                                           
    exit;                                                                                      
fi                                                                                             

timeout 2 time sleep 5                                                                         
if [[ $? == 124 ]]                                                                             
then                                                                                           
    exit;                                                                                      
fi                                                                                             

在我的系统上,产生:

0.00user 0.00system 0:01.00elapsed 0%CPU (0avgtext+0avgdata 1696maxresident)k
0inputs+0outputs (0major+73minor)pagefaults 0swaps

不是最漂亮的输出,但它在第一行之后停止:时间sleep 3sleep 5的结果永远不会显示。

请注意timeout是一个GNU coreutils命令,并未安装在任何地方(如果它可以安装在您的系统上)。退出状态也可能不同:默认值为124,但测试$? != 0可能更好。

答案 1 :(得分:2)

一种方法是同时在后台启动sleep和您的流程,看看谁先完成。

请注意,下面假设在下面的代码下面没有启动其他后台进程:

timeout=30 # set this to the number of seconds you want

timed_run() {
  time "$@"
}

# use: abort_on_timeout timeout_in_seconds command_here
abort_on_timeout() {
  local sleep_pid cmd_pid retval
  local seconds=$1; shift
  wait # reap any preexisting background processes so they don't interfere
  sleep "$seconds" & sleep_pid=$!
  "$@" & cmd_pid=$!
  wait; retval=$?
  if kill -0 "$sleep_pid"; then
    # cmd finished before sleep
    kill "$sleep_pid"
    return "$retval"
  fi
  # sleep finished before cmd, so exit the whole script
  kill "$cmd"
  exit 1
}

abort_on_timeout "$timeout" ./A 10
abort_on_timeout "$timeout" ./A 20
abort_on_timeout "$timeout" ./A 30

当然,您可以使用循环:

v=10
while :; do
  abort_on_timeout "$timeout" ./A "$v"
  v=$((v + 10))
done

答案 2 :(得分:0)

const char *env[] = {NULL};
const char *argv[] = {NULL};
const char *script = "my_script.sh";
const int time_interval = 10;

/* ... */

pid_t parent = getpid();
pid_t child = vfork();
if (child == -1) {
    printf("Pity! Cannot do vfork\n");
}
else if (child == 0) {
    execve(script, argv, env);
}
else {
    sleep(time_interval);
    kill(9, child);
}