쉘 작업 번호를 PID에 매핑

쉘 작업 번호를 PID에 매핑

저는 셸 작업 제어를 사용하여 오래 실행되는 작업을 백그라운드로 밀어넣어 데이터가 변동하는 동안 해당 작업을 계속 실행할 수 있도록 합니다.

예를 들어, 실행 중인 작업을 볼 수 있습니다 jobs.

jobs
[2]-  Running                 su - root -c "..." &  (wd: /backup/rsnapshot)
[3]+  Running                 sleep 60 &

다음 명령을 사용하여 이들 중 하나를 제어할 수 있습니다.% 작업 사양fg %su또는 와 같은 구문 kill %3.

다음을 사용하면 jobs -lPID도 얻습니다 .

jobs -l
[2]- 31736 Running                 su - root -c "..." &  (wd: /backup/rsnapshot)
[3]+  2269 Running                 sleep 60 &

bashI have 를 사용 jobs -x하면 이POSIX 아님. 이게 번역할 수 있는 유일한 방법인가요?% 작업 사양아니면 합리적인(더 나은) 대안이 있습니까? 다른 껍질은 어떻습니까?

jobs -x echo %3
2269

내 목표 사용 사례는% 작업 사양확장 예정투명하게%2다음과 같이 처리 되도록 명령줄에 해당 PID를 입력하세요.31736

pidtree %2    # pidtree 31736

이것은 처리될 수 있지만 jobs -x pidtree %2그렇게 우아하거나 편리하지는 않습니다.

최소한 하나의 답변을 Targeting 원 bash하지만 작업 제어가 포함된 다른 쉘에 대한 기여는 환영합니다. 특히 POSIX 솔루션이 있는 경우 더욱 그렇습니다.

답변1

현재 작업 목록에서 bash사용자 정의 설정 변수를 동적으로 제공하여 이에 가까워질 수 있습니다.$PROMPT_COMMAND

개념의 증거:

$ PROMPT_COMMAND='unset ${!j*}; eval "$(jobs -l | awk '\''{gsub("[^[:digit:] ]", ""); printf "j%d=%d\n", $1, $2}'\'')"'

그런 다음 숫자가 없다고 가정하고 pidtree $j2로 대체합니다 . 그렇지 않으면 인용해야 하므로 키를 두 번 더 입력해야 합니다.pidtree %2$IFS$j2

답변2

몇 가지 명령에 대해서만 이 작업을 수행하려는 경우 프로그래밍 가능한 완료가 옵션이 될 것입니다. 이는 POSIX가 아닐 가능성이 높지만 적어도 여러 셸에서 작동합니다(그리고 기본 메커니즘이 동일할 필요도 없습니다).

따라서 입력하면 pidtree %2Tab쉘이 이를 다음으로 변환합니다.

pidtree 31736

고급스럽고 편리한 것 같아요.

단점: 이러한 명령에 대한 기존 완료 구성을 유지하려면 수동 개입이 필요합니다(예: 함수를 먼저 실행하고 불일치가 있으면 원래 함수를 호출하도록 합니다).

_pidtree () {
    local job pid
    if [[ ${COMP_WORDS[COMP_CWORD]} =~ ^%[1-9][0-9]* ]]; then
        job="${COMP_WORDS[COMP_CWORD]:1}"
        pid="$(jobs -l | awk -v job="$job" '$1 ~ "^\\[" job "\\]" { print $2; }')"
        COMPREPLY=("$pid")
    fi
}

complete -F _pidtree pidtree

이것은 잘 작동합니다 bash. 없이도 수행할 수 awk있으며 확실히 더 호환되는 방식으로 수행할 수 있습니다.

줄바꿈을 포함하는 작업에는 문제가 있을 수 있지만 이는 대화형 셸이므로 악용될 위험은 없는 것 같습니다.

답변3

백그라운드 작업을 생성할 때 PID만 기억하는 것이 가장 쉽지 않나요?

bash:

declare -a bgjobpids
[...]
do_some_thing &
pid=$!
index=${#bgjobpids[@]}
bgjobpids[index]=$pid
[...]
do_some_thing_else &
pid=$!
index=${#bgjobpids[@]}
bgjobpids[index]=$pid

관련 정보