我搜索了一些关于如何执行此操作的信息,但找不到解决方案。我出于必要而使用进程替换。我想等待所有处理完成后再继续。
我如何获得我的PID下面的“跑步者”功能所以我可以等吗?
基本上它的作用是执行,然后记录标准输出,然后将错误和错误记录到标准输出。除了无序响应之外,效果良好。
"${@}" 1> >(2log) 2> >(2log2scr | tee >&2)
pid=???? # <<< HERE
while [ -e /proc/"$pid" ]; do sleep 0.1; done # <<< HERE
我尝试了类似以下的操作,但不起作用:
pid=$(exec sh -c "${@}" 1>>(2log) 2>>(2log2scr | tee >&2) )
这部分有效 - 它破坏了我的评估:
> runner success & > while [ -e /proc/$! ]; do sleep 0.1; done
输出
started running FAILURE: **** 4.4.19(1)-release **** finished running EVAL IS:
感谢您的帮助。
如果您需要它进行测试,完整的脚本如下:
#!/bin/bash
logfile='test.log'
logprep() {
local in=$(cat)
in=$(echo "$in" | perl -pe 's/\**//smig') # for proc subst
# Return prepped string
echo -e "preped for logging: '$in'"
}
2log() {
local in=$(cat)
if [ "$in" != '' ]; then
echo -e "$in" | logprep >>"$logfile" # out to logfile
fi
return 0
}
2log2scr() {
local in=$(cat)
# 2scr
if [ "'$in'" != '' ]; then echo -e "$in"; fi
# 2log
if [ "$in" != '' ]; then
echo -e "$in" > >(logprep >>"$logfile") # out to logfile
fi
return 0
}
runner () {
echo -e "started running\n"
"${@}" 1> >(2log) 2> >(2log2scr | tee >&2) # <<< RUNNER
#while [ -e /proc/15435 ]; do sleep 0.1; done # <<< HERE
echo -e "finished running\n"
}
success() {
eval 'version=$(echo "SUCCESS: **** ${BASH_VERSION} ****")'
echo -e "$version"; return 0
}
failure() {
eval 'version=$(echo "FAILURE: **** ${BASH_VERSION} ****")'
echo -e "$version" 1>&2; return 64
}
runner success # to test a successful command
runner failure # to test a command that errs
echo "EVAL IS: $version"
答案1
后台进程的 pid 可以从 $!环境变量,如果它已放入后台(通过在命令末尾添加 & ),即
my-cmd &
echo $!
您可以探索的另一个选项是在执行的 shell 中使用 $$ (当前 shell 的 pid),例如
exec sh -c 'echo $$ > t.pid && sleep 10' &
echo $! # <-- pid of spawned shell
pid=$(cat t.pid) # <-- pid of execed process in shell
像这样的东西会给你一个名为 t.pid 的临时文件中的 pid
答案2
我在不破坏 EVAL 的情况下使其工作的唯一方法是:
runner () {
echo -e "started running\n"
"${@}" 1> >(2log) 2> >(2log2scr | tee >&2)
while [ -e /proc/$! ]; do sleep 0.1; done
echo -e "$pid finished running\n"
}
这里的区别在于,我只是简单地访问,$!
没有任何事先要求。所有建议都提到 $!如果我们像这样调用我们的例程,就可以访问:
my-cmd &
echo $!
看来这不是一个要求,我们可以$!
在任何复杂的例程之后简单地访问,例如"${@}" 1> >(2log) 2> >(2log2scr | tee >&2)
不在任何地方使用“&”