Bash跳过睡眠并转到下一个循环迭代

时间:2016-02-25 22:23:16

标签: bash loops sleep

我有一个看起来像这样的bash循环:

something(){
    echo "something"
}

while true; do
    something
    sleep 10s
done | otherCommand

当循环处于睡眠状态时,我希望能够从终端运行一个函数,该函数将跳过睡眠步骤并继续循环的下一次迭代。

例如,如果脚本已经休眠5秒钟,我希望命令停止脚本休眠,继续循环的下一次迭代,运行something,然后再次继续休眠。 / p>

4 个答案:

答案 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键跳过超时。