eck*_*art 67 linux shell ubuntu
有没有一种简单的方法可以让特定命令(只能通过 终止Ctrl-C
)自动运行 5 分钟?
例如:
minute-command 5-minutes ping www.google.com
Run Code Online (Sandbox Code Playgroud)
或任何其他不会自行终止的命令。
我希望能够指定一个时间限制,而不仅仅是 5 分钟。
Gom*_*dor 87
实际上,这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
Run Code Online (Sandbox Code Playgroud)
Tob*_*ght 68
有(至少)两个程序提供此功能:
姓名
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
Run Code Online (Sandbox Code Playgroud)
/-----------------------------+------------+----------------\
| 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) |
\-----------------------------+------------+----------------/
Run Code Online (Sandbox Code Playgroud)
笔记:
timeout
始终SIGKILL
用作其最后的信号。timeout
当子程序这样做时,没有任何功能可以通过信号退出。这两个程序的退出状态不同,但很难清楚地概括,因此我建议您自己查阅手册页。
由于timeout
默认安装在更多系统上(coreutils
在许多发行版中是标准包),我建议您使用它,除非您需要timelimit
.
Has*_*tur 17
bash
内置,没有coreutils我发现该解决方案bash
依赖于内置命令而不调用外部可执行文件。它适用于最终甚至没有安装coreutils [ 1 ] 的系统
YourCommand & read -t 300 ; kill $! # 1st version
YourCommand & read -t 300 || kill $! # 2nd version
Run Code Online (Sandbox Code Playgroud)
说明:像往常一样,当您在后台使用 发送命令时&
,其 PID 存储在内部变量中$!
(存在于dash
, csh
, bash
, tcsh
, zsh
...的现代版本中)。
真正使 shell 有所不同的是内置命令read
[ 2 ]和选项的存在-t
。在第一个版本中,如果用户在指定的秒数之前未完成一行输入,则指令将终止并生成错误返回代码。
-t TIMEOUT 如果在 TIMEOUT 秒内未读取完整的输入行,则导致读取超时并返回失败。
第二个版本与第一个版本相同,但您只需按 即可中止终止超时enter。
实际上,or 运算符仅在命令以非零的返回码退出时才||
执行该kill
语句read
,例如超时到期时。如果您enter在那一刻之前按下,它将返回 0,并且不会终止您之前的命令。
当coreutils的是你的系统,你有没有需要保存的时间和资源来调用外部程序, timeout
并sleep
并达到你的目标两者的完美方式。
timeout
使用timeout
简单明了。
最终,-k
如果第一个失败,您也可以考虑使用发送额外终止信号的选项。
timeout 5m YourCommand # 3rd version
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
说明
YourCommand
然后您的 shell执行sleep
5 分钟。当它完成时,最后一个后台进程 ( $!
) 将被杀死。你停止你的外壳。
YourCommand
并立即将该 PID 存储在变量中$pid
。然后您在后台执行5 分钟的小睡及其随后的命令,该命令将终止该存储的 PID。由于您在后台发送了这组命令,因此您不会停止您的 shell。您需要将 PID 存储在一个变量中,因为 的值$!
可以通过在后台最终执行另一个程序来更新。简而言之,您可以避免杀死错误进程或根本没有进程的风险。
$$
,然后执行您保留在前台的命令。 ()
将其 PID 存储在变量 ( cmdpid
) 中的子 shell ,并使用在后台执行中发送的另一个子 shell 杀死自己,然后在前台运行 YourCommand。
当然在每个版本中你都可以发送你需要的kill信号,从默认的到极端的 kill -9
,只在真正需要的时候使用。
参考
Tob*_*ght 11
对于您的特定情况,大多数实现ping
支持-c
或--count
在特定数量的 ping 后终止:
ping -c 300 host.example.com
Run Code Online (Sandbox Code Playgroud)
有关更通用的解决方案,请参阅其他答案。
你可以用一个简单的脚本来做到这一点:
#!/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
Run Code Online (Sandbox Code Playgroud)
(信号 SIGINT=2 根据 Matija Nalis 在下面评论中的建议使用)。
对(不常见的?)bash 表达式的解释$@:...
:位置参数, ( $*, $@, "$*", "$@"
) 承认以下额外规范,例如:
"${@:START:COUNT}"
Run Code Online (Sandbox Code Playgroud)
这意味着:在所有参数中,取其中的 COUNT 个,第一个取在 STARTth 位置的参数;如果 COUNT 被省略,从 STARTth 位置开始,将它们全部取出到最后。请记住,这$0
是程序名称。如果 START 为负数,则从末尾开始计数,并记住 COUNT不能为负数,因此最后一个参数是"${@:-1}"
。此外,几乎总是在双引号内包含位置参数。
归档时间: |
|
查看次数: |
28111 次 |
最近记录: |