如何停止在后台运行的无限 while 循环?

如何停止在后台运行的无限 while 循环?

有没有一种选项可以让无限 while 循环在后台作为函数运行时,在任何给定时刻停止并使用局部变量开始运行?我已经尝试了很多选项,但我找不到一个完美的解决方案。我让它工作的唯一方法是从 while 循环中读取外部文本文件。并在程序中的指定点将 0 或 1 写入该文本文件。

我现在正在做的是:

    #!/bin/bash

intr(){ while true                  # function endless while loop start 
        do 
        sleep 0.5                   # execute function every x time
        var1=`grep "1" 0or1.txt`    # read file 0or1.txt 
        if [ -n "$var1" ] ; then    # if text =1 execute function, 
        # do some magic..
        fi
        done
        }                           # end function
        intr &                      # execute function as bg process

#some code                          # located some where in the script
echo "1" > 0or1.txt                 # write 1 to start function 
#some code                          # this should be a local variable??


#some code                          # located some where in the script               
echo "0" > 0or1.txt                 # write 0 to stop function
#some code                          # this should be a local variable??

答案1

从问题下方评论中的讨论可以看出,OP 想要的是暂停后台功能。引用:

@ serg,主要目的是让此代码发挥中断的作用。在程序的几个点上,我需要禁用“中断”,在几个点上,我需要启用它。(这不是一次性事件。)

可以使用 和 来实现-SIGSTOP-SIGCONT这两个信号本质上是进程的暂停和播放按钮。下面是我最初发布的修改后的演示脚本。本质上,我已经生成了函数 endless 作为后台进程,并首先发送-SIGSTOP和 然后-SIGCONT发送给它。这里最重要的一点是,即使主进程退出,后台进程仍将继续运行,因此在我的示例中,中断不会停止输出到控制台,除非我kill 1234从另一个终端发出,其中 1234 是从脚本报告的函数 PID。所以要注意

$ ./someInfiniteLoop.sh                                        
We are in the main, about to spawn the interrupt function
Parent process (the script itself)  7119
Captured 7120
>>>> HEY I'M THE 1 SECOND INTERRUPT
>>>> HEY I'M THE 1 SECOND INTERRUPT
>>>> HEY I'M THE 1 SECOND INTERRUPT
Sending SIGSTOP to  7120
Funciton paused; waiting 3 seconds
You could do something else when function is paused
Function resumed
>>>> HEY I'M THE 1 SECOND INTERRUPT
>>>> HEY I'M THE 1 SECOND INTERRUPT
>>>> HEY I'M THE 1 SECOND INTERRUPT

演示脚本源代码:

#!/bin/bash
# use the line bellow if you want to silence error messages
# exec 2>/dev/null
endless()
{
  while true
  do

     echo ">>>> HEY I'M THE 1 SECOND INTERRUPT"
  sleep 1
  done
}

echo 'We are in the main, about to spawn the interrupt function'
echo "Parent process (the script itself)  $$"

endless &
endless_pid="$!"
echo "Captured $endless_pid"
sleep 3

echo 'Sending SIGSTOP to ' $endless_pid
kill -SIGSTOP $endless_pid
[ $? -eq 0  ] && echo 'Funciton paused; waiting 3 seconds' || echo 'Something is wrong'

echo 'You could do something else when function is paused'

sleep 3

kill -SIGCONT $endless_pid

[ $? -eq 0   ] && echo 'Function resumed' || echo 'Something is wrong'

sleep 3 && exit 0 

您可能还想阅读:


答案2

使用break内置函数来停止while循环。

help break

break: break [n]

Exit for, while, or until loops.

Exit a FOR, WHILE or UNTIL loop.  If N is specified, break N enclosing
loops.

Exit Status:
The exit status is 0 unless N is not greater than or equal to 1.

因此,在您的代码片段中,您可以执行以下操作:

while :; do
    if [ -n "$var1" ] ; then
        break
    fi
done

或者更短一点:

while :; do
    [ -n "$var1" ] && break
done

要将任何输入传递给函数,请使用位置参数,即参数。第一个参数可以通过 检索$1,第二个参数$2等等。

例如,如果您foobar通过以下方式调用函数:

foobar spam

在函数中你可以使用以下方法spam获取$1

$ foobar () { echo "This is $1" ;}

$ foobar spam
This is spam

相关内容