Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.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_Loops_Sleep - Fatal编程技术网

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

Bash跳过睡眠并转到下一个循环迭代,bash,loops,sleep,Bash,Loops,Sleep,我有一个bash循环,如下所示: something(){ echo "something" } while true; do something sleep 10s done | otherCommand 当循环处于睡眠状态时,我希望能够从终端运行一个函数,该函数将跳过睡眠步骤并继续循环的下一个迭代 例如,如果脚本已休眠5秒,我希望命令停止脚本休眠,继续循环的下一次迭代,运行something,然后再次继续休眠。如果要跳过休眠,请使用类似可以触摸的文件的内容: if

我有一个bash循环,如下所示:

something(){
    echo "something"
}

while true; do
    something
    sleep 10s
done | otherCommand
当循环处于睡眠状态时,我希望能够从终端运行一个函数,该函数将跳过睡眠步骤并继续循环的下一个迭代


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

如果要跳过休眠,请使用类似可以触摸的文件的内容:

if [ ! -f /tmp/skipsleep ]; then
   sleep 10
fi

当你想中断sleep命令时,杀了它

你可以用
read-t10
阅读命名管道,而不是睡觉:命名管道的道具由“另一个家伙”添加

现在,每当另一个脚本使用
echo>~/.myfifo
写入fifo时,循环将跳过当前等待并继续下一次迭代

这样,不同的用户或不同的脚本等待10秒不会相互干扰

若脚本在前台运行,而您正在等待,则下面的解决方案可以工作。当然,您需要一个有效的循环退出条件。您还可以检查输入的值,并对其采取不同的操作。在这种情况下,按除“j”以外的任何键都将迭代循环。按下“j”将通过管道将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 

这并非万无一失,但可能足够强大:

要中断
sleep
命令,请运行:

pkill -f 'sleep 10s'
请注意,当
sleep
被终止时,运行
sleep
命令的脚本会向stderr打印如下内容:
:行:终止:15 sleep 10s
。奇怪的是,您不能用
sleep 10s2>/dev/null
抑制此脚本;要抑制它,您必须将
2>/dev/null
作为一个整体应用于
while
循环,或者作为一个整体应用于脚本调用

正如@miken32在评论中指出的,该命令试图杀死调用命令行与
sleep 10s
匹配的所有命令,但是-除非您以
root
身份运行-由于没有杀死其他用户进程的权限,只有在您处理的进程之间匹配的情况下,才会成功杀死

为了更安全,您可以显式地将匹配限制到您自己的进程:

pkill -u "$(id -u)" -f 'sleep 10s'

但是,真正安全的使用要求您捕获正在运行的脚本的PID(进程ID),将其保存到一个文件中,并使用该文件中的PID与
pkill
-p选项,该选项限制与指定PID的子进程的匹配-请参阅(谢谢,@miken32)

如果是交互式的,那么就用“read-t”而不是“sleep”


然后,只需按enter键即可跳过超时。

我希望它跳过当前睡眠。说它已经睡了5秒钟了。我希望命令停止脚本休眠,转到循环的下一个迭代,运行
something
,然后再次开始休眠。如果我正确读取了该文件,它不会这样做,而是总是跳过睡眠,如果文件
/tmp/skipsleep
。对不起,如果我的问题含糊不清。我看不出这对我有什么帮助。请详细说明。没有,但他问他如何能中断睡眠并重复循环。循环应该是回显字符串并将其传输到某个东西,而不是调用它。上次我尝试了这个,它似乎对循环不起作用。我不知道为什么。现在可以了,谢谢。值得一提的是,这将杀死所有
sleep
命令,无论它们是否从脚本启动。可能不值得担心,但对于您要杀死的命令不是唯一的情况,有一个详细的解决方案。@miken32是的,我正试图对PID做一些事情。由于某种原因,当睡眠处于循环状态时,它似乎不起作用。也许我只是个傻瓜。@Marcel-在你的另一篇帖子中,你没有告诉pkill要杀死哪个子进程。如果您尝试
pkill-P$PARENTPID-f sleep
,它应该可以工作。用脚本的pid替换
$PARENTPID
pkill -u "$(id -u)" -f 'sleep 10s'