我有一个看起来像这样的bash循环:
something(){
echo "something"
}
while true; do
something
sleep 10s
done | otherCommand
当循环处于睡眠状态时,我希望能够从终端运行一个函数,该函数将跳过睡眠步骤并继续循环的下一次迭代。
例如,如果脚本已经休眠5秒钟,我希望命令停止脚本休眠,继续循环的下一次迭代,运行something
,然后再次继续休眠。 / p>
答案 0 :(得分:2)
这不是万无一失的,但可能足够强大:
要中断sleep
命令,请运行:
pkill -f 'sleep 10s'
请注意,当sleep
被杀时,运行sleep
命令的脚本会向stderr输出类似以下内容的内容:<script-path>: line <line-number>: <pid> Terminated: 15 sleep 10s
。奇怪的是,您无法使用sleep 10s 2>/dev/null
来抑制此脚本;要禁止它,你必须将2>/dev/null
作为一个整体应用于while
循环,或者作为一个整体应用于脚本调用。
正如@ miken32在评论中指出的那样,此命令会尝试终止其调用命令行与sleep 10s
匹配的所有命令 - 除非您以root
运行 - 由于缺少杀死其他用户进程的权限,因此只能处理您的之间的匹配才会成功。
为了安全 r ,您可以明确地将匹配限制为您自己的进程:
pkill -u "$(id -u)" -f 'sleep 10s'
但是,真正安全使用需要捕获正在运行的脚本的PID(进程ID),将其保存到文件中,并使用pkill
的{{1}}选项中的该文件中的PID,它限制匹配指定PID的子进程 - 请参阅this answer(谢谢,@ miken32)。
答案 1 :(得分:0)
如果您想跳过睡眠,请使用类似您可以触摸的文件:
if [ ! -f /tmp/skipsleep ]; then
sleep 10
fi
如果要中断睡眠命令,请将其删除!
答案 2 :(得分:0)
您可以使用read -t 10
从命名管道中读取而不是睡眠:由#34添加命名管道的道具;其他人&#34;
something()
{
echo "something"
}
somethingelse()
{
echo "something else"
}
mkfifo ~/.myfifo
while cat ~/.myfifo; do true; done |
while true
do
something
read -t 10 && somethingelse
done
现在每当另一个脚本用echo > ~/.myfifo
写入fifo时,循环将跳过当前的等待并继续下一次迭代。
这样,等待十秒的不同用户或不同脚本不会相互干扰。
如果脚本在前台运行并且您正在等待,则下面的解决方案有效。当然,您需要一个有效的循环退出条件。您还可以检查输入的值并以不同方式对其进行操作。在这种情况下,按任何键除了&#39; j&#39;将迭代循环。按&#39; j&#39;将somethingelse的输出传递给awk。
something()
{
echo "something"
}
somethingelse()
{
echo "something else"
}
while true; do
something |awk '{print "piping something: " $0 }'
read -t 3 -s -n 1 answer
if [ $? == 0 ]; then
echo "you didn't want to wait!"
fi
if [ "$answer" = "j" ]; then
somethingelse | awk '{print "piping something else: " $0 }'
fi
done
答案 3 :(得分:0)
如果是交互式,那么只需使用“read -t#”而不是“sleep#”。
然后您可以按Enter键跳过超时。