macos - 经过一定的时间,macOS 命令行 命令自动终止命令

  显示原文与译文双语对照的内容
143 0

我想在一定时间后自动终止命令。 我想到了一个类似这样的接口:


% constrain 300./foo args



如果在 5分钟后仍在运行,它将使用"实参"运行"。/foo",但自动终止。

如果将这个概念推广到它的他约束,如autokilling使用过多的内存,这可以能是有用的。

有任何现有的工具,或者有人写过这样的东西?

补充:乔纳森的解决方案正好是我想到的,它在linux上工作起来像一个魅力。 我把SIGRTMIN解除了,它可以编译好,但是信号不会发送到子进程。 任何人都知道如何在Mac上工作?

[ 添加:请注意,可以从Mac和其他在Mac工作的更新获得更新。

时间: 原作者:

78 3

我到达这个聚会时很晚,但我没有看到我最喜欢的技巧。

在 *NIX, 下,alarm(2)execve(2) 中被继承,而SIGALRM在默认情况下是致命的。 因此,你通常可以简单地:


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



$ doalarm 300./foo.sh args



或者安装一个简单的包装器来为你做这个。

优势只涉及一个 PID,该机制简单。 如果 ./foo.sh 退出"太快"并使用它的PID,则不会终止错误的进程。 你不需要在音乐会上工作的多个 shell 子流程,它可以正确地完成,但是比较容易。

时间限制时间限制进程无法操纵它的闹钟时钟,因为这可能会清除继承的警报。 显然,它既不能阻止或者忽略 SIGALRM,但同样也可以说 for 。

有些( 很旧,我觉得) 系统用 alarm(2) 实现 sleep(2),甚至有些程序员现在使用 alarm(2) 作为 I/O 和其他操作的内置内部超时机制。 不过,根据我的经验,这种技术适用于你希望进行时间限制的大量流程。

原作者:
69 0

GNU Coreutils包括在许多系统上默认安装的超时命令。

https://www.gnu.org/software/coreutils/manual/html_node/timeout-invocation.html

要监视 free -m 一分钟,然后通过发送一个术语信号杀死它:


timeout 1m watch free -m



原作者:
136 1

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


(/path/to/slow command with options ) & sleep 5 ; kill $!



这将在括号内运行第一个命令,在括号内运行五秒钟,然后。 整个操作同步运行,换句话说,在忙于等待缓慢命令时,你将无法使用 shell 。 如果这不是你想要的,那么就可以添加另一个 & 。

$ 变量是一个Bash内置,它包含最近启动的子shell的进程 ID 。! 在括号中没有&很重要,这样做就会丢失进程 ID 。

原作者:
71 0

我有一个名为 timeout的程序,它是用C 编写的,最初是从 1989开始,但是自从那时起。

Update: 由于 macOS 函数没有定义,因为在闹钟超时后,signal() 函数没有被定义,所以这段代码无法在X 上编译,并且在运行时超时失败。 我有一个新版本的timeout.c,它处理这些问题( 使用 sigaction() 而不是 signal() ) 。 以前一样,请与我联系以获得 10K 个压缩的tar文件,其中包含源代码和手动页面( 查看我的个人资料) 。


/*


@(#)File: $RCSfile: timeout.c,v $


@(#)Version: $Revision: 4.6 $


@(#)Last changed: $Date: 2007/03/01 22:23:02 $


@(#)Purpose: Run command with timeout monitor


@(#)Author: J Leffler


@(#)Copyright: (C) JLSS 1989,1997,2003,2005-07


*/



#define _POSIX_SOURCE/* Enable kill() in <unistd.h> on Solaris 7 */


#define _XOPEN_SOURCE 500



#include <stdio.h>


#include <stdlib.h>


#include <signal.h>


#include <errno.h>


#include <unistd.h>


#include <sys/types.h>


#include <sys/wait.h>


#include"stderr.h"



#define CHILD 0


#define FORKFAIL -1



static const char usestr[] ="[-vV] -t time [-s signal] cmd [arg.. .]";



#ifndef lint


/* Prevent over-aggressive optimizers from eliminating ID string */


const char jlss_id_timeout_c[] ="@(#)$Id: timeout.c,v 4.6 2007/03/01 22:23:02 jleffler Exp $";


#endif/* lint */



static void catcher(int signum)


{


 return;


}



int main(int argc, char **argv)


{


 pid_t pid;


 int tm_out;


 int kill_signal;


 pid_t corpse;


 int status;


 int opt;


 int vflag = 0;



 err_setarg0(argv[0]);



 opterr = 0;


 tm_out = 0;


 kill_signal = SIGTERM;


 while ((opt = getopt(argc, argv,"vVt:s:"))!= -1)


 {


 switch(opt)


 {


 case 'V':


 err_version("TIMEOUT", &"@(#)$Revision: 4.6 $ ($Date: 2007/03/01 22:23:02 $)"[4]);


 break;


 case 's':


 kill_signal = atoi(optarg);


 if (kill_signal <= 0 || kill_signal> = SIGRTMIN)


 err_error("signal number must be between 1 and %dn", SIGRTMIN - 1);


 break;


 case 't':


 tm_out = atoi(optarg);


 if (tm_out <= 0)


 err_error("time must be greater than zero (%s)n", optarg);


 break;


 case 'v':


 vflag = 1;


 break;


 default:


 err_usage(usestr);


 break;


 }


 }



 if (optind> = argc || tm_out == 0)


 err_usage(usestr);



 if ((pid = fork()) == FORKFAIL)


 err_syserr("failed to forkn");


 else if (pid == CHILD)


 {


 execvp(argv[optind], &argv[optind]);


 err_syserr("failed to exec command %sn", argv[optind]);


 }



/* Must be parent -- wait for child to die */


 if (vflag)


 err_remark("time %d, signal %d, child PID %un", tm_out, kill_signal, (unsigned)pid);


 signal(SIGALRM, catcher);


 alarm((unsigned int)tm_out);


 while ((corpse = wait(&status))!= pid && errno!= ECHILD)


 {


 if (errno == EINTR)


 {


/* Timed out -- kill child */


 if (vflag)


 err_remark("timed out - send signal %d to process %dn", (int)kill_signal, (int)pid);


 if (kill(pid, kill_signal)!= 0)


 err_syserr("sending signal %d to PID %d -", kill_signal, pid);


 corpse = wait(&status);


 break;


 }


 }



 alarm(0);


 if (vflag)


 {


 if (corpse == (pid_t) -1)


 err_syserr("no valid PID from waiting -");


 else


 err_remark("child PID %u status 0x%04Xn", (unsigned)corpse, (unsigned)status);


 }



 if (corpse!= pid)


 status = 2;/* Dunno what happened! */


 else if (WIFEXITED(status))


 status = WEXITSTATUS(status);


 else if (WIFSIGNALED(status))


 status = WTERMSIG(status);


 else


 status = 2;/* Dunno what happened! */



 return(status);


}



如果你想要'stderr.h'和'stderr.c'的'官方'代码,请联系我( 查看我的个人资料) 。

原作者:
...