이 "${@}" 1> >(2log) 2> >(2log2scr | tee >&2)의 PID를 가져올 수 없습니다.

이 "${@}" 1> >(2log) 2> >(2log2scr | tee >&2)의 PID를 가져올 수 없습니다.

이 작업을 수행하는 방법에 대한 정보를 검색했지만 해결책을 찾을 수 없습니다. 나는 필요에 따라 프로세스 대체를 사용합니다. 계속하기 전에 모든 처리가 완료될 때까지 기다리고 싶습니다.

내 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 $!

탐색할 수 있는 또 다른 옵션은 실행 중인 셸에서 $$(현재 셸의 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) 어디에도 "&"를 사용하지 마세요

관련 정보