如何在 Posix shell 脚本中将变量设置为无限循环的输出?
How can I set a variable to the output of an infinite loop in Posix shell script?
您可以像在 Bash、sh 等中那样将变量设置为子 shell 的输出
$ var=$(echo "2")
$ echo $var
2
您还可以将变量设置为循环完成后的输出。
$ i=0
$ var=$(while [ $i -ne 4 ]; do echo "$i"; i=$((i+1)); done)
$ echo "$var"
0
1
2
3
我是否可以分叉此循环,永远保持 运行ning,并在引用变量时获取最新版本的变量?我尝试了以下代码,但没有输出。
$ i=0
$ var=$(while true; do echo "$i"; i=$((i+1)); sleep 1; done) &
$ sleep 2
$ echo "$var"
我认为变量从未设置,因为循环从未完成。我希望这里的输出为“3”,如果我在 echo "$var"
两秒后输出“5”。正如@user2864740 所述,该问题与在后台分叉的进程有关。这里有解决方案吗,如果我希望我的其余代码为 运行 而无限循环为 运行ning?
你不能按照你的要求去做。但是,您可以使用命名管道代替变量。一个进程可以写入管道,另一个进程可以从中读取。
mkfifo p
i=0
while :; do
echo "$i"
i=$((i+1))
sleep 2
done > p &
while IFS= read -r num; do
echo "$num"
sleep 1
done < p
命名管道实际上就像一个文件,但具有固定大小。如果文件已满,编写器将阻塞,直到 space 通过读取文件完成。同样,如果管道为空,reader 将阻塞,直到有人写入它。
I would like for the output to be "3" here, and if I echo "$var" two seconds later, the output "5".
您不能从(子)进程内部自动分配变量。但是您可以使用每次迭代都会覆盖的临时文件访问循环中的最新值。
当然您可以将值保存在变量中 (var=$(< file)
) 或直接访问文件 (cat file
)。
trap 'kill $(jobs -p); rm -f loopoutput' EXIT
i=0
while true; do echo "$i" > loopoutput; i=$((i+1)); sleep 1; done &
sleep 4
cat loopoutput
sleep 2
cat loopoutput
打印
3
5
trap
仅用于在脚本完成后结束循环并删除临时文件。
您可以像在 Bash、sh 等中那样将变量设置为子 shell 的输出
$ var=$(echo "2")
$ echo $var
2
您还可以将变量设置为循环完成后的输出。
$ i=0
$ var=$(while [ $i -ne 4 ]; do echo "$i"; i=$((i+1)); done)
$ echo "$var"
0
1
2
3
我是否可以分叉此循环,永远保持 运行ning,并在引用变量时获取最新版本的变量?我尝试了以下代码,但没有输出。
$ i=0
$ var=$(while true; do echo "$i"; i=$((i+1)); sleep 1; done) &
$ sleep 2
$ echo "$var"
我认为变量从未设置,因为循环从未完成。我希望这里的输出为“3”,如果我在 echo "$var"
两秒后输出“5”。正如@user2864740 所述,该问题与在后台分叉的进程有关。这里有解决方案吗,如果我希望我的其余代码为 运行 而无限循环为 运行ning?
你不能按照你的要求去做。但是,您可以使用命名管道代替变量。一个进程可以写入管道,另一个进程可以从中读取。
mkfifo p
i=0
while :; do
echo "$i"
i=$((i+1))
sleep 2
done > p &
while IFS= read -r num; do
echo "$num"
sleep 1
done < p
命名管道实际上就像一个文件,但具有固定大小。如果文件已满,编写器将阻塞,直到 space 通过读取文件完成。同样,如果管道为空,reader 将阻塞,直到有人写入它。
I would like for the output to be "3" here, and if I echo "$var" two seconds later, the output "5".
您不能从(子)进程内部自动分配变量。但是您可以使用每次迭代都会覆盖的临时文件访问循环中的最新值。
当然您可以将值保存在变量中 (var=$(< file)
) 或直接访问文件 (cat file
)。
trap 'kill $(jobs -p); rm -f loopoutput' EXIT
i=0
while true; do echo "$i" > loopoutput; i=$((i+1)); sleep 1; done &
sleep 4
cat loopoutput
sleep 2
cat loopoutput
打印
3
5
trap
仅用于在脚本完成后结束循环并删除临时文件。