这个问题已经在这里有了答案:
- 允许运行一段时间后终止进程 3个答案
有没有一种简单的方法可以让特定命令(只能通过终止Ctrl-C
)自动运行5分钟?
例如:
minute-command 5-minutes ping www.google.com
或任何其他不会终止的命令。
我希望能够指定一个时限,而不仅仅是5分钟。
这个问题已经在这里有了答案:
有没有一种简单的方法可以让特定命令(只能通过终止Ctrl-C
)自动运行5分钟?
例如:
minute-command 5-minutes ping www.google.com
或任何其他不会终止的命令。
我希望能够指定一个时限,而不仅仅是5分钟。
Answers:
有(至少)两个程序提供此功能:
名称
timelimit
—有效地限制了流程的绝对执行时间概要
timelimit [-pq] [-S killsig] [-s warnsig] [-T killtime] [-t warntime] command [arguments ...]
和
名称
timeout
-运行有时间限制的命令概要
timeout [OPTION] DURATION COMMAND [ARG]...
timeout [OPTION]
它们的包装如下:
$ dlocate `which timeout timelimit`
timelimit: /usr/bin/timelimit
coreutils: /usr/bin/timeout
/-----------------------------+------------+----------------\
| Feature | timelimit | timeout |
+=============================+============+================+
| time to run | -t time | first argument |
+-----------------------------+------------+----------------+
| terminate signal | -s signal | -s signal |
+-----------------------------+------------+----------------+
| grace period | -T time | -k time |
+-----------------------------+------------+----------------+
| kill signal | -S signal | (note 1) |
+-----------------------------+------------+----------------+
| propagate signals | -p | (note 2) |
\-----------------------------+------------+----------------/
笔记:
timeout
始终将SIGKILL
其用作最后一个信号。timeout
子程序这样做时,没有任何功能可以退出并带有信号。这两个程序的退出状态有所不同,但是很难一目了然,因此我建议您自己查阅手册页。
由于timeout
默认情况下已安装在更多系统上(coreutils
在许多发行版中是标准软件包),因此除非您需要所提供的额外功能,否则我建议您使用它timelimit
。
timelimit
。请参阅如何杀死进程,并确保没有重复使用PID以获得有关它们和GNU超时的更多信息。
timeout
包含在GNU coreutils中,timelimit
没有。您可以没有安装任何一个,或者两个都没有安装。对于第二个时间,报告了时间限制执行命令,并在给定时间后使用给定信号终止生成的过程。首先发送“警告”信号,然后在超时后发送 “ kill”信号,类似于init(8)在关机时进行操作。因此,中间行为甚至有所不同。
timeout
是一种解决方法。
实际上,这timeout
是为了:
TIMEOUT(1) User Commands TIMEOUT(1)
NAME
timeout - run a command with a time limit
SYNOPSIS
timeout [OPTION] DURATION COMMAND [ARG]...
timeout [OPTION]
DESCRIPTION
Start COMMAND, and kill it if still running after DURATION.
lx@lxtp:~$ dpkg -S /usr/bin/timeout
coreutils: /usr/bin/timeout
bash
内置,无coreutils我发现该解决方案可以bash
依靠内置命令运行而无需调用外部可执行文件。它适用于最终甚至没有安装coreutils [ 1 ]的系统
YourCommand & read -t 300 ; kill $! # 1st version
YourCommand & read -t 300 || kill $! # 2nd version
说明:像往常一样,当你在后台发送一个命令&
,它的PID被存储到内部变量$!
(存在于现代版的dash
,csh
,bash
,tcsh
,zsh
...)。
外壳之间真正有所不同的是内置命令read
[ 2 ]和option的存在-t
。在第一个版本中,如果用户在指定的秒数内未完成输入行,则该指令将终止并生成错误返回码。
-t TIMEOUT 如果超时时间内未读取完整的输入行,则导致读取超时并返回失败。
第二个版本与第一个版本相同,但是您可以按来终止终止超时enter。
的确,仅当命令以返回码(不为零)退出(如超时到期)时,or运算符才||
执行kill
语句read
。如果您enter在那一刻之前按下,它将返回0,并且不会终止您先前的命令。
当coreutils存在于您的系统中时,您无需节省时间和资源来调用外部程序, timeout
并且sleep
这两者都是实现目标的完美方法。
timeout
的使用timeout
很简单。
最终,-k
如果第一个失败,您也可以考虑使用该选项发送附加的终止信号。
timeout 5m YourCommand # 3rd version
sleep
与sleep
您一起可以使用自己的幻想或获得一些启发[ 3 ]。请注意,您可以将命令保留在后台或前台(例如,top
通常需要放在前台)。
YourCommand & sleep 5m; kill $! # 4th Background
YourCommand & pid=$! ; (sleep 5m; kill $pid;) & # 5th Background
bash -c '(sleep 5m; kill $$) & exec YourCommand' # 6th Foreground
(cmdpid=$BASHPID; (sleep 5m; kill $cmdpid) & exec YourCommand) # 7th Foreground
说明
YourCommand
然后在shell中执行sleep
5分钟。完成后,最后的后台进程($!
)将被终止。您停止外壳。
YourCommand
然后立即将该PID存储在变量中$pid
。然后,您在后台执行5分钟的小睡及其随后的命令,该命令将杀死存储的PID。由于您是在后台发送这组命令的,因此您不会停止外壳程序。您需要将PID存储在变量中,因为的值$!
可以通过最终在后台执行另一个程序来更新。简而言之,您可以避免杀死错误的过程或根本没有任何过程的风险。
$$
,然后执行您保留在前台的命令。 ()
,该子外壳将其PID存储在变量(cmdpid
)中,并在后台执行中发送的另一个子外壳中杀死自己,然后在前台运行YourCommand。
当然,在每个版本中,您都可以发送所需的kill信号,从默认的信号到极端的信号 kill -9
,仅在真正需要时才使用。
参考文献
对于您的特定情况,大多数ping
支持实施-c
或--count
在特定数量的ping之后终止:
ping -c 300 host.example.com
有关更一般的解决方案,请参见其他答案。
ping
为一个具体示例提供的。他不想为每个不同的程序提供个案解决方案。
您可以使用以下简单脚本来完成此操作:
#!/bin/bash
#
# $1 is the time to let the program run, and $2, $3, ... are the command itself.
#
"${@:2}" &
PID=$!
sleep "${@:1:1}"
kill -2 $PID
(信号SIGINT = 2,根据下面的评论中Matija Nalis的建议使用)。
bash表达式的解释(不常见?)$@:...
:位置参数($*, $@, "$*", "$@"
)接受以下额外说明,例如:
"${@:START:COUNT}"
这意味着:在所有参数中,取COUNT个,第一个作为STARTth位置的参数;如果省略COUNT,则将它们全部取到最后,从STARTth位置开始。请记住,这$0
是程序名称。如果START为负,则从末尾开始计数,并记住COUNT 不能为负,因此最后一个参数为"${@:-1}"
。同样,几乎总是在双引号中包含位置参数。
$1
非常困难。另外,您也可以sleep "$1"
在中输入内容countdown
。
time=$1; shift
,然后不需要位置参数的数组切片语法。但是,是的,这要简单得多。
ctrl-c
最好尝试kill -INT
而不是尝试尝试kill -9
(或至少-9
在几秒钟后尝试,如果第一个程序不成功-它使程序有机会干净退出而不留下临时文件)等等)