此示例在我的 zsh 终端上运行,但在我的 zsh 脚本上下文中不运行:
sh -c 'sleep 15 && echo asdf' &
x=$(jobs)
echo $x
在命令行上按预期工作(输出[1] + running sh -c 'sleep 15 && echo asdf'
)
但是以下脚本不会打印:
#!/usr/bin/zsh
sh -c 'sleep 3 && echo hi' & sh -c 'sleep 5 && echo bye' &
while (( ${#jobstates} )); do
sleep 1;
x=$(jobs)
echo $x #DOES NOT print to stdout
jobs #DOES print to stdout
jobs | grep "hi" #DOES NOT print to stdout
y=$(ls)
echo $y #DOES print to stdout
done
jobs
为什么循环中间会有特殊之处?
我正在尝试做的事情的背景:我只是想检查我已启动的作业,以便在等待它们完成/完成时可以查询有关它们的信息。
答案1
没有使用过 zsh,但是从总体上来说:
- 您是否已验证
$(jobs)
确实产生了输出?(顺便说一句:我会将其附在"
) - ... 也可能存在同样的问题
jobs | grep "hi"
hi
(的输出中没有jobs
)
答案2
我认为jobs
在某些情况下直接写入终端(而不是标准输出)是因为它被认为仅在交互式环境中有用。此行为可能是硬编码的。
在我的系统上(zsh 5.9.0.1-dev
Arch Linux),我成功地通过这个丑陋的技巧将作业的输出放入 shell 变量中:
temp_file=$(mktemp)
jobs > $temp_file
x=$(< $temp_file)
print $x
rm $temp_file
答案3
最终得到了没有临时文件的解决方案:
function debounce_sync() {
sleep 10
echo "after 10 secs!!!"
}
unset last_pid
while read; do
if [[ -v last_pid ]]; then
kill -9 $last_pid >/dev/null 2>&1
fi
debounce_sync &
last_pid=$!
done
unset last_pid
最后启动的作业的 pid 存储在$!
您可以将它们存储在数组变量中,或者直接终止前一个作业以仅保留单个正在运行的作业