我有一个(至少对我来说)相当复杂的问题。
见下文:
#! /bin/bash
notify=false
a=0
while ((a <= 50))
do
echo $a
a=$(echo "$a+1" | bc)
sleep 3s
done
当我运行脚本时,while 循环开始执行。完成后,脚本退出。
问题:
如果我将脚本中的变量设置notify
为 true,则需要发生一些事情。那就是notify_now
当 $a 达到 25 时,它会将变量(例如)设置为 true。当notify_now
设置为 true 时,它会回显通知这不会中断 while 循环。见下文:
...
24
25
The variable $a has reached 25
26
...
但是当我设置notify
为 false 时,它不会发出任何通知。见下文:
...
24
25
26
...
在我的实际情况中,执行以下操作不是一种选择:
#! /bin/bash
notify=false
a=0
while ((a <= 50))
do
echo $a
if ((a = 25)) && [[ $notify = true ]]
then
echo "The variable \$a has reached 25"
fi
a=$(echo "$a+1" | bc)
sleep 3s
done
总之:
我需要一段代码,当变量设置为 true 时,该代码可以在循环之外运行。该代码需要在后台运行,以便 while 循环可以在前台运行。当后台的那段代码注意到前台的变量 $a 已达到 25 时,它会在终端中回显一句话。
我取得了多大的进展:
- 这段代码可能是一个将被调用的函数
- 该函数将在后台运行,但回显在前台(使用
&
,但我在这方面真的很差,所以这就是我问这个问题的原因) - 代码将循环运行,直到 $a 达到 25(因此它将以 while 循环的速度检查 $a,直到它达到 25)
但我似乎无法让任何实际的代码发挥作用。
谢谢!
答案1
这时,bash DEBUG trap 就派上用场了。参考https://www.gnu.org/software/bash/manual/bash.html#index-trap
如果notify.sh包含
#!/bin/bash
has_been_notified=false
notify() {
$has_been_notified && return
if [[ -v a ]] && ((a == 25)); then
echo "This is the notification: value is $a"
has_been_notified=true
fi
}
while getopts :n opt; do
[[ $opt == n ]] && trap notify DEBUG
done
shift $((OPTIND - 1))
a=23
while ((a <= 27)); do
echo $((a++))
done
请注意,我使用的是命令行选项,而不是 $notify 变量。使用任何对您方便的选项即可。
运行它:
$ bash notify.sh # no notify
23
24
25
26
27
$ bash notify.sh -n # with notify
23
24
This is the notification: value is 25
25
26
27
基本上,每个命令之前都会调用 DEBUG 陷阱(有关详细信息,请参阅手册)。这就是我添加“has_been_notified”标志的原因,这样通知只会出现一次。
对于这项工作来说,这是一个相当沉重的打击,但是 bash 没有提供任何更精细的陷阱,例如当变量获得新值时的陷阱。
没有命令行选项:
#!/bin/bash
notify_flag=false
has_been_notified=false
notify() {
$has_been_notified && return
if [[ -v a ]] && ((a == 25)); then
echo "This is the notification: value is $a"
has_been_notified=true
fi
}
[[ $notify_flag == true ]] && trap notify DEBUG
a=23
while ((a <= 27)); do
echo $((a++))
done