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

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

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

% constrain 300./foo args

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

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

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

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

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

时间:原作者:0个回答

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'的'官方'代码,请联系我( 查看我的个人资料) 。

原作者:
...