Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/15.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
如何限制BASH脚本的运行时间_Bash_Cygwin - Fatal编程技术网

如何限制BASH脚本的运行时间

如何限制BASH脚本的运行时间,bash,cygwin,Bash,Cygwin,我有一个长时间运行的BASH脚本,我在Windows上的CYGWIN下运行 我想将脚本的运行时间限制为30秒,并在超过此限制时自动终止。理想情况下,我希望能够对任何命令执行此操作 例如: sh-3.2$ limittime -t 30 'myscript.sh' 或 在cygwin下,ulimit命令似乎不起作用 我愿意接受任何想法。您可以将该命令作为后台作业运行(即使用“&”),将bash变量用于“上次命令运行的pid”,睡眠必要的时间,然后使用该pid运行kill。请签出。我们的想法是将m

我有一个长时间运行的BASH脚本,我在Windows上的CYGWIN下运行

我想将脚本的运行时间限制为30秒,并在超过此限制时自动终止。理想情况下,我希望能够对任何命令执行此操作

例如:

sh-3.2$ limittime -t 30 'myscript.sh'

在cygwin下,ulimit命令似乎不起作用


我愿意接受任何想法。

您可以将该命令作为后台作业运行(即使用“&”),将bash变量用于“上次命令运行的pid”,睡眠必要的时间,然后使用该pid运行
kill

请签出。我们的想法是将myscript.sh作为脚本的子进程运行,并记录其PID,如果运行时间过长,则将其杀死。

下面的脚本演示了如何使用后台任务执行此操作。第一部分在10秒限制后终止60秒的进程。第二次尝试终止已退出的进程。请记住,如果您将超时设置得非常高,进程ID可能会滚动,您将杀死错误的进程,但这更像是一个理论问题-超时必须非常大,并且您必须启动许多进程

#!/usr/bin/bash

sleep 60 &
pid=$!
sleep 10
kill -9 $pid

sleep 3 &
pid=$!
sleep 10
kill -9 $pid
以下是我的Cygwin盒上的输出:

$ ./limit10
./limit10: line 9:  4492 Killed sleep 60
./limit10: line 11: kill: (4560) - No such process
如果只想等待流程完成,则需要输入循环并进行检查。由于
sleep 1
和其他命令实际上需要超过1秒(但不会超过1秒)的时间,因此这种方法的准确性稍差。使用此脚本替换上面的第二部分(“code>echo$proc”和“
date
”命令用于调试,我不希望它们出现在最终解决方案中)

它基本上是循环的,检查进程是否每秒都在运行。如果没有,它将使用一个特殊值退出循环,以不尝试杀死子循环。否则它就会超时并杀死孩子

下面是睡眠3的输出:

Mon Feb  9 11:10:37 WADT 2009
pax 4268 2476 con 11:10:37 /usr/bin/sleep
pax 4268 2476 con 11:10:37 /usr/bin/sleep
Mon Feb  9 11:10:41 WADT 2009
Mon Feb  9 11:10:41 WADT 2009
和一个
睡眠60

Mon Feb  9 11:11:51 WADT 2009
pax 4176 2600 con 11:11:51 /usr/bin/sleep
pax 4176 2600 con 11:11:51 /usr/bin/sleep
pax 4176 2600 con 11:11:51 /usr/bin/sleep
pax 4176 2600 con 11:11:51 /usr/bin/sleep
pax 4176 2600 con 11:11:51 /usr/bin/sleep
pax 4176 2600 con 11:11:51 /usr/bin/sleep
pax 4176 2600 con 11:11:51 /usr/bin/sleep
pax 4176 2600 con 11:11:51 /usr/bin/sleep
pax 4176 2600 con 11:11:51 /usr/bin/sleep
pax 4176 2600 con 11:11:51 /usr/bin/sleep
Mon Feb  9 11:12:03 WADT 2009
Mon Feb  9 11:12:03 WADT 2009
./limit10: line 20:  4176 Killed sleep 60
请参阅其功能已集成到较新coreutils中的脚本:

#!/bin/sh

# Execute a command with a timeout

# License: LGPLv2
# Author:
#    http://www.pixelbeat.org/
# Notes:
#    Note there is a timeout command packaged with coreutils since v7.0
#    If the timeout occurs the exit status is 124.
#    There is an asynchronous (and buggy) equivalent of this
#    script packaged with bash (under /usr/share/doc/ in my distro),
#    which I only noticed after writing this.
#    I noticed later again that there is a C equivalent of this packaged
#    with satan by Wietse Venema, and copied to forensics by Dan Farmer.
# Changes:
#    V1.0, Nov  3 2006, Initial release
#    V1.1, Nov 20 2007, Brad Greenlee <brad@footle.org>
#                       Make more portable by using the 'CHLD'
#                       signal spec rather than 17.
#    V1.3, Oct 29 2009, Ján Sáreník <jasan@x31.com>
#                       Even though this runs under dash,ksh etc.
#                       it doesn't actually timeout. So enforce bash for now.
#                       Also change exit on timeout from 128 to 124
#                       to match coreutils.
#    V2.0, Oct 30 2009, Ján Sáreník <jasan@x31.com>
#                       Rewritten to cover compatibility with other
#                       Bourne shell implementations (pdksh, dash)

if [ "$#" -lt "2" ]; then
    echo "Usage:   `basename $0` timeout_in_seconds command" >&2
    echo "Example: `basename $0` 2 sleep 3 || echo timeout" >&2
    exit 1
fi

cleanup()
{
    trap - ALRM               #reset handler to default
    kill -ALRM $a 2>/dev/null #stop timer subshell if running
    kill $! 2>/dev/null &&    #kill last job
      exit 124                #exit with 124 if it was running
}

watchit()
{
    trap "cleanup" ALRM
    sleep $1& wait
    kill -ALRM $$
}

watchit $1& a=$!         #start the timeout
shift                    #first param was timeout for sleep
trap "cleanup" ALRM INT  #cleanup after timeout
"$@"& wait $!; RET=$?    #start the job wait for it and save its return value
kill -ALRM $a            #send ALRM signal to watchit
wait $a                  #wait for watchit to finish cleanup
exit $RET                #return the value
$ timeout --help
Usage: timeout [OPTION] DURATION COMMAND [ARG]...
  or:  timeout [OPTION]
Start COMMAND, and kill it if still running after DURATION.

Mandatory arguments to long options are mandatory for short options too.
      --preserve-status
                 exit with the same status as COMMAND, even when the
                   command times out
      --foreground
                 when not running timeout directly from a shell prompt,
                   allow COMMAND to read from the TTY and get TTY signals;
                   in this mode, children of COMMAND will not be timed out
  -k, --kill-after=DURATION
                 also send a KILL signal if COMMAND is still running
                   this long after the initial signal was sent
  -s, --signal=SIGNAL
                 specify the signal to be sent on timeout;
                   SIGNAL may be a name like 'HUP' or a number;
                   see 'kill -l' for a list of signals
      --help     display this help and exit
      --version  output version information and exit

DURATION is a floating point number with an optional suffix:
's' for seconds (the default), 'm' for minutes, 'h' for hours or 'd' for days.

If the command times out, and --preserve-status is not set, then exit with
status 124.  Otherwise, exit with the status of COMMAND.  If no signal
is specified, send the TERM signal upon timeout.  The TERM signal kills
any process that does not block or catch that signal.  It may be necessary
to use the KILL (9) signal, since this signal cannot be caught, in which
case the exit status is 128+9 rather than 124.

GNU coreutils online help: <http://www.gnu.org/software/coreutils/>
Full documentation at: <http://www.gnu.org/software/coreutils/timeout>
or available locally via: info '(coreutils) timeout invocation'
#/垃圾箱/垃圾箱
#执行带有超时的命令
#许可证:LGPLv2
#作者:
#    http://www.pixelbeat.org/
#注:
#注意,自v7.0以来,有一个与coreutils打包的超时命令
#如果发生超时,则退出状态为124。
#这有一个异步(和bug)等价物
#用bash打包的脚本(在我的发行版中的/usr/share/doc/下),
#这是我写完这篇文章后才注意到的。
#我后来再次注意到,有一个C等价物
#Wietse Venema的《撒旦》,Dan Farmer复制给法医。
#变化:
#V1.0,2006年11月3日,首次发布
#2007年11月20日,Brad Greenlee
#使用“CHLD”使其更便于携带
#信号规格,而不是17。
#V1.3,2009年10月29日,Ján Sáreník
#即使这在dash、ksh等下运行。
#它实际上并没有超时。所以现在就实施bash。
#同时将超时退出时间从128更改为124
#匹配coreutils。
#V2.0,2009年10月30日,Ján Sáreník
#重写以涵盖与其他系统的兼容性
#伯恩shell实现(pdksh、dash)
如果[“$#”-lt“2”];然后
echo“用法:`basename$0`timeout_in_seconds command”>&2
echo“示例:`basename$0`2睡眠3 | | echo超时”>&2
出口1
fi
清理()
{
陷阱-ALRM#将处理程序重置为默认值
kill-ALRM$a2>/dev/null#如果正在运行,则停止计时器子shell
kill$!2>/dev/null&&#终止上一个作业
退出124#如果它正在运行,则使用124退出
}
watchit()
{
陷阱“清理”ALRM
睡眠1美元&等待
杀死ALRM$$
}
watchit$1&a=$#启动超时
shift#第一个参数是睡眠超时
陷阱“清理”ALRM INT#超时后清理
“$@”等待$!;RET=$#启动作业并等待它并保存其返回值
kill-ALRM$a#发送ALRM信号给watchit
等待$a#等待watchit完成清理
退出$RET#返回值
以下是coreutils下的所有“超时”选项:

#!/bin/sh

# Execute a command with a timeout

# License: LGPLv2
# Author:
#    http://www.pixelbeat.org/
# Notes:
#    Note there is a timeout command packaged with coreutils since v7.0
#    If the timeout occurs the exit status is 124.
#    There is an asynchronous (and buggy) equivalent of this
#    script packaged with bash (under /usr/share/doc/ in my distro),
#    which I only noticed after writing this.
#    I noticed later again that there is a C equivalent of this packaged
#    with satan by Wietse Venema, and copied to forensics by Dan Farmer.
# Changes:
#    V1.0, Nov  3 2006, Initial release
#    V1.1, Nov 20 2007, Brad Greenlee <brad@footle.org>
#                       Make more portable by using the 'CHLD'
#                       signal spec rather than 17.
#    V1.3, Oct 29 2009, Ján Sáreník <jasan@x31.com>
#                       Even though this runs under dash,ksh etc.
#                       it doesn't actually timeout. So enforce bash for now.
#                       Also change exit on timeout from 128 to 124
#                       to match coreutils.
#    V2.0, Oct 30 2009, Ján Sáreník <jasan@x31.com>
#                       Rewritten to cover compatibility with other
#                       Bourne shell implementations (pdksh, dash)

if [ "$#" -lt "2" ]; then
    echo "Usage:   `basename $0` timeout_in_seconds command" >&2
    echo "Example: `basename $0` 2 sleep 3 || echo timeout" >&2
    exit 1
fi

cleanup()
{
    trap - ALRM               #reset handler to default
    kill -ALRM $a 2>/dev/null #stop timer subshell if running
    kill $! 2>/dev/null &&    #kill last job
      exit 124                #exit with 124 if it was running
}

watchit()
{
    trap "cleanup" ALRM
    sleep $1& wait
    kill -ALRM $$
}

watchit $1& a=$!         #start the timeout
shift                    #first param was timeout for sleep
trap "cleanup" ALRM INT  #cleanup after timeout
"$@"& wait $!; RET=$?    #start the job wait for it and save its return value
kill -ALRM $a            #send ALRM signal to watchit
wait $a                  #wait for watchit to finish cleanup
exit $RET                #return the value
$ timeout --help
Usage: timeout [OPTION] DURATION COMMAND [ARG]...
  or:  timeout [OPTION]
Start COMMAND, and kill it if still running after DURATION.

Mandatory arguments to long options are mandatory for short options too.
      --preserve-status
                 exit with the same status as COMMAND, even when the
                   command times out
      --foreground
                 when not running timeout directly from a shell prompt,
                   allow COMMAND to read from the TTY and get TTY signals;
                   in this mode, children of COMMAND will not be timed out
  -k, --kill-after=DURATION
                 also send a KILL signal if COMMAND is still running
                   this long after the initial signal was sent
  -s, --signal=SIGNAL
                 specify the signal to be sent on timeout;
                   SIGNAL may be a name like 'HUP' or a number;
                   see 'kill -l' for a list of signals
      --help     display this help and exit
      --version  output version information and exit

DURATION is a floating point number with an optional suffix:
's' for seconds (the default), 'm' for minutes, 'h' for hours or 'd' for days.

If the command times out, and --preserve-status is not set, then exit with
status 124.  Otherwise, exit with the status of COMMAND.  If no signal
is specified, send the TERM signal upon timeout.  The TERM signal kills
any process that does not block or catch that signal.  It may be necessary
to use the KILL (9) signal, since this signal cannot be caught, in which
case the exit status is 128+9 rather than 124.

GNU coreutils online help: <http://www.gnu.org/software/coreutils/>
Full documentation at: <http://www.gnu.org/software/coreutils/timeout>
or available locally via: info '(coreutils) timeout invocation'
$timeout--帮助
用法:超时[选项]持续时间命令[ARG]。。。
或:超时[选项]
启动命令,如果在持续时间后仍在运行,则将其杀死。
长选项的强制性参数对于短选项也是强制性的。
--保持身份
以与命令相同的状态退出,即使
命令超时
--前景
当不直接从shell提示符运行timeout时,
允许命令读取TTY并获取TTY信号;
在此模式下,命令的子项不会超时
-k、 --kill after=持续时间
如果命令仍在运行,也会发送终止信号
这是在最初的信号发出后很久
-s、 --信号=信号
指定超时时要发送的信号;
信号可以是“HUP”之类的名称或数字;
有关信号列表,请参见“kill-l”
--帮助显示此帮助并退出
--版本输出版本信息并退出
持续时间是一个带有可选后缀的浮点数:
“s”表示秒(默认值),“m”表示分钟,“h”表示小时,“d”表示天。
如果命令超时,并且未设置--preserve status,则使用退出
现状124。否则,以命令状态退出。如果没有信号
指定时,在超时时发送术语信号。“信号”一词会导致死亡
任何不阻止或捕捉该信号的进程。这可能是必要的
使用KILL(9)信号,由于无法捕获该信号,其中
案例退出状态为128+9,而不是124。
GNU coreutils联机帮助:
完整文档位于:
或通过以下方式在本地提供:info
$ timeout --help
Usage: timeout [OPTION] DURATION COMMAND [ARG]...
  or:  timeout [OPTION]
Start COMMAND, and kill it if still running after DURATION.

Mandatory arguments to long options are mandatory for short options too.
      --preserve-status
                 exit with the same status as COMMAND, even when the
                   command times out
      --foreground
                 when not running timeout directly from a shell prompt,
                   allow COMMAND to read from the TTY and get TTY signals;
                   in this mode, children of COMMAND will not be timed out
  -k, --kill-after=DURATION
                 also send a KILL signal if COMMAND is still running
                   this long after the initial signal was sent
  -s, --signal=SIGNAL
                 specify the signal to be sent on timeout;
                   SIGNAL may be a name like 'HUP' or a number;
                   see 'kill -l' for a list of signals
      --help     display this help and exit
      --version  output version information and exit

DURATION is a floating point number with an optional suffix:
's' for seconds (the default), 'm' for minutes, 'h' for hours or 'd' for days.

If the command times out, and --preserve-status is not set, then exit with
status 124.  Otherwise, exit with the status of COMMAND.  If no signal
is specified, send the TERM signal upon timeout.  The TERM signal kills
any process that does not block or catch that signal.  It may be necessary
to use the KILL (9) signal, since this signal cannot be caught, in which
case the exit status is 128+9 rather than 124.

GNU coreutils online help: <http://www.gnu.org/software/coreutils/>
Full documentation at: <http://www.gnu.org/software/coreutils/timeout>
or available locally via: info '(coreutils) timeout invocation'