zsh 脚本没有打印“jobs”命令的输出?

zsh 脚本没有打印“jobs”命令的输出?

此示例在我的 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,但是从总体上来说:

  1. 您是否已验证$(jobs)确实产生了输出?(顺便说一句:我会将其附在"
  2. ... 也可能存在同样的问题jobs | grep "hi" hi(的输出中没有jobs

答案2

我认为jobs在某些情况下直接写入终端(而不是标准输出)是因为它被认为仅在交互式环境中有用。此行为可能是硬编码的。

在我的系统上(zsh 5.9.0.1-devArch 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 存储在$!

您可以将它们存储在数组变量中,或者直接终止前一个作业以仅保留单个正在运行的作业

相关内容