我无法获取此“${@}”的 PID 1> >(2log) 2> >(2log2scr | tee >&2)

我无法获取此“${@}”的 PID 1> >(2log) 2> >(2log2scr | tee >&2)

我搜索了一些关于如何执行此操作的信息,但找不到解决方案。我出于必要而使用进程替换。我想等待所有处理完成后再继续。

我如何获得我的PID下面的“跑步者”功能所以我可以等吗?

基本上它的作用是执行,然后记录标准输出,然后将错误和错误记录到标准输出。除了无序响应之外,效果良好。

"${@}" 1> >(2log) 2> >(2log2scr | tee >&2) 
pid=????                                      # <<< HERE
while [ -e /proc/"$pid" ]; do sleep 0.1; done # <<< HERE

我尝试了类似以下的操作,但不起作用:

  1. pid=$(exec sh -c "${@}" 1>>(2log) 2>>(2log2scr | tee >&2) )

  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) 不在任何地方使用“&”

相关内容