Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/unix/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Macos 命令行命令,用于在一定时间后自动终止命令_Macos_Unix_Command Line_Utilities_Cpu Usage - Fatal编程技术网

Macos 命令行命令,用于在一定时间后自动终止命令

Macos 命令行命令,用于在一定时间后自动终止命令,macos,unix,command-line,utilities,cpu-usage,Macos,Unix,Command Line,Utilities,Cpu Usage,我想在一段时间后自动终止一个命令。我想到了这样一个界面: % constrain 300 ./foo args 它将运行带有“args”的“/foo”,但如果在5分钟后仍在运行,则会自动将其杀死 将这一思想推广到其他约束可能会很有用,例如,如果进程使用太多内存,则自动终止进程 有没有现成的工具可以做到这一点,或者有人写过这样的东西 补充:Jonathan的解决方案正是我所想的,它在linux上很有魅力,但我无法让它在MacOSX上运行。我去掉了SIGRTMIN,它可以很好地编译,但是信号没有被

我想在一段时间后自动终止一个命令。我想到了这样一个界面:

% constrain 300 ./foo args
它将运行带有“args”的“/foo”,但如果在5分钟后仍在运行,则会自动将其杀死

将这一思想推广到其他约束可能会很有用,例如,如果进程使用太多内存,则自动终止进程

有没有现成的工具可以做到这一点,或者有人写过这样的东西

补充:Jonathan的解决方案正是我所想的,它在linux上很有魅力,但我无法让它在MacOSX上运行。我去掉了SIGRTMIN,它可以很好地编译,但是信号没有被发送到子进程。有人知道如何在Mac上工作吗


[补充:请注意,Jonathan提供了一个在Mac和其他地方工作的更新。]

我有一个名为
timeout
的程序,它可以做到这一点——最初是用C编写的,1989年开始,但此后定期更新


更新:此代码无法在MacOS X上编译,因为没有定义SIGRTMIN,在MacOS X上运行时无法超时,因为“signal()”函数在报警超时后恢复“wait()”,这不是必需的行为。我有一个新版本的'timeout.c',它处理这两个问题(使用'sigaction()'而不是'signal()`)。如前所述,请联系我获取10K Gzip tar文件,其中包含源代码和手册页(请参阅我的个人资料)。
/*
@(#)文件:$RCSfile:timeout.c,v$
@(#)版本:$修订版:4.6$
@(#)上次更改:$日期:2007/03/01 22:23:02$
@(#)用途:使用超时监视器运行命令
@(#)作者:J Leffler
@(#)版权所有:(C)JLSS 1989199720032005-07
*/
#在Solaris 7上定义_POSIX_SOURCE/*启用kill()*/
#定义_XOPEN_源500
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括“stderr.h”
#定义子0
#定义FORKFAIL-1
静态常量char usestr[]=“[-vV]-t时间[-s信号]cmd[arg…]”;
#ifndef皮棉
/*防止过度激进的优化器消除ID字符串*/
const char jlss_id_timeout_c[]=“@(#)$id:timeout.c,v4.6 2007/03/01 22:23:02 jleffler Exp$”;
#endif/*lint*/
静态空隙捕捉器(内部信号)
{
返回;
}
int main(int argc,字符**argv)
{
pid_t pid;
int tm_out;
int kill_信号;
尸体;
智力状态;
int-opt;
int vflag=0;
err_setarg0(argv[0]);
opterr=0;
tm_out=0;
kill_信号=SIGTERM;
而((opt=getopt(argc,argv,“vVt:s:”)!=-1)
{
开关(opt)
{
案例“V”:
错误版本(“超时”和“@(#)$修订版:4.6$($日期:2007/03/01 22:23:02$)”[4]);
打破
案例s:
杀伤信号=atoi(optarg);
if(终止信号=SIGRTMIN)
err_error(“信号号必须介于1和%d\n之间”,SIGRTMIN-1);
打破
案例“t”:
tm_out=atoi(optarg);
如果(tm|u out=argc | tm|u out==0)
错误用法(usestr);
if((pid=fork())==FORKFAIL)
err_syserr(“未能分叉”);
else if(pid==子级)
{
execvp(argv[optind],&argv[optind]);
err_syserr(“未能执行命令%s\n”,argv[optind]);
}
/*必须是父母--等待孩子死亡*/
if(vflag)
错误注释(“时间%d,信号%d,子PID%u\n”,tm\u out,终止信号,(未签名)PID);
信号机(信号机、捕捉器);
报警((无符号整数)tm_out);
while((尸体=等待(&status))!=pid&&errno!=ECHILD)
{
如果(errno==EINTR)
{
/*超时-杀死孩子*/
if(vflag)
错误注释(“超时-发送信号%d到进程%d\n”,(int)终止信号,(int)pid);
if(kill(pid,kill_信号)!=0)
err_syserr(“将信号%d发送到PID%d-”,kill_信号,PID);
尸体=等待(&状态);
打破
}
}
报警(0);
if(vflag)
{
如果(尸体==(pid_t)-1)
err_syserr(“没有来自等待的有效PID-”;
其他的
错误注释(“子PID%u状态0x%04X\n”,(未签名)尸体,(未签名)状态);
}
如果(尸体!=pid)
状态=2;/*我不知道发生了什么事*/
否则,如果(妻子退出(状态))
状态=WEXITSTATUS(状态);
否则如果(WIFSIGNALED(状态))
状态=WTERMSIG(状态);
其他的
状态=2;/*我不知道发生了什么事*/
返回(状态);
}

如果您想要“stderr.h”和“stderr.c”的“官方”代码,请与我联系(请参阅我的个人资料)。

还有ulimit,可用于限制子进程的执行时间

ulimit -t 10
将进程的CPU时间限制为10秒

要实际使用它来限制新进程,而不是当前进程,您可能希望使用包装器脚本:

#! /usr/bin/env python

import os
os.system("ulimit -t 10; other-command-here")

其他命令可以是任何工具。我运行了不同排序算法的Java、Python、C和Scheme版本,并记录了它们所用的时间,同时将执行时间限制为30秒。Cocoa Python应用程序生成了各种命令行(包括参数),并将时间整理成CSV文件,但实际上是just fluff位于上面提供的命令之上。

Perl一行,仅用于踢:

perl -e '$s = shift; $SIG{ALRM} = sub { print STDERR "Timeout!\n"; kill INT => $p }; exec(@ARGV) unless $p = fork; alarm $s; waitpid $p, 0' 10 yes foo

这会将“foo”打印10秒,然后超时。将“10”替换为任意秒数,将“yes foo”替换为任意命令。

也许我不理解这个问题,但这听起来直接可行,至少在bash中是这样的:

( /path/to/slow command with options ) & sleep 5 ; kill $!
这将在括号内运行第一个命令五秒钟,然后将其终止。整个操作同步运行,即在shell忙于等待慢速命令时,您将无法使用shell。如果这不是您想要的,则应该可以添加另一个&

$!
变量是一个
( /path/to/slow command with options ) & sleep 5 ; kill $!
perl -e '$s = shift; $SIG{ALRM} = sub { print STDERR "Timeout!\n"; kill INT => $p; exit 77 }; exec(@ARGV) unless $p = fork; alarm $s; waitpid $p, 0; exit ($? >> 8)' 10 yes foo
# This function is called with a timeout (in seconds) and a pid.
# After the timeout expires, if the process still exists, it attempts
# to kill it.
function timeout() {
    sleep $1
    # kill -0 tests whether the process exists
    if kill -0 $2 > /dev/null 2>&1 ; then
        echo "killing process $2"
        kill $2 > /dev/null 2>&1
    else
        echo "process $2 already completed"
    fi
}

<your command> &
cpid=$!
timeout 3 $cpid
wait $cpid > /dev/null 2>&
exit $?
## run a command, aborting if timeout exceeded, e.g. timed-run 20 CMD ARGS ...
timed-run() {
  # timeout in seconds
  local tmout="$1"
  shift
  env CMD_TIMEOUT="$tmout" expect -f - "$@" <<"EOF"
# expect script follows
eval spawn -noecho $argv
set timeout $env(CMD_TIMEOUT)
expect {
   timeout {
      send_error "error: operation timed out\n"
      exit 1
   }
   eof
}
EOF
}

#!/bin/bash

if [[ $# < 2 ]]; then
  echo "Usage: $0 timeout cmd [options]"
  exit 1
fi

TIMEOUT="$1"
shift

BOSSPID=$$

(
  sleep $TIMEOUT
  kill -9 -$BOSSPID
)&
TIMERPID=$!

trap "kill -9 $TIMERPID" EXIT

eval "$@"
$ doalarm () { perl -e 'alarm shift; exec @ARGV' "$@"; } # define a helper function

$ doalarm 300 ./foo.sh args
#!/bin/sh
# Usage: timelimit.sh secs cmd [ arg ... ]
exec perl -MPOSIX -e '$SIG{ALRM} = sub { print "timeout: @ARGV\n"; kill(SIGTERM, -$$); }; alarm shift; $exit = system @ARGV; exit(WIFEXITED($exit) ? WEXITSTATUS($exit) : WTERMSIG($exit));' "$@"
timeout 1m watch free -m
#!/bin/sh
( some_slow_task ) & pid=$!
( sleep $TIMEOUT && kill -HUP $pid ) 2>/dev/null & watcher=$!
wait $pid 2>/dev/null && pkill -HUP -P $watcher
( sleep 20 ) & pid=$!
( sleep 2 && kill -HUP $pid ) 2>/dev/null & watcher=$!
if wait $pid 2>/dev/null; then
    echo "Slow task finished"
    pkill -HUP -P $watcher
    wait $watcher
else
    echo "Slow task interrupted"
fi
( sleep 2 ) & pid=$!
( sleep 20 && kill -HUP $pid ) 2>/dev/null & watcher=$!
if wait $pid 2>/dev/null; then
    echo "Slow task finished"
    pkill -HUP -P $watcher
    wait $watcher
else
    echo "Slow task interrupted"
fi