Obtém informações do processo (o comando, etc) do pid

0

Eu tenho este código:

     for job in 'jobs -p'; do
         code=0;
         wait ${job} || code=$?
         if [[ "${code}" != "0" ]]; then
            echo "At least one job failed with exit code => ${code}" ;
            exit 1;
         fi
     done

logo após a linha:         echo "Pelo menos um trabalho falhou com o código de saída = > $ {CODE}";

Eu quero adicionar uma linha que registra o comando que falhou, algo assim:

     for job in 'jobs -p'; do
         code=0;
         wait ${job} || code=$?
         if [[ "${code}" != "0" ]]; then
            echo "At least one job failed with exit code => ${code}" ;
            echo "The job that failed was $(ps -p ${job})"
            exit 1;
         fi
     done

não que job seja apenas o pid do subprocesso. O problema é que esta linha:

echo "The job that failed was $(ps -p ${job})"

não é sobre nada - eu preciso do comando que foi executado, dado o pid = job.

    
por Alexander Mills 24.03.2018 / 05:50

3 respostas

3

No ponto em que você está executando o comando ps , o processo já foi encerrado (você está lidando com o código de retorno, certo?)

Basta alterar a lógica para executar o comando ps anteriormente no script, antes do wait e armazenar isso em uma variável:

for job in $(jobs -p); do
    process_info=$(ps -p "${job}" -o args=)
    wait "${job}" || {
        code=$?
        echo "Job running [${process_info}] failed with exit code ${code}." >&2
        exit 1
    }
done
    
por 24.03.2018 / 06:00
0

Como foi apontado , você não pode usar ps em um processo não existente.

Se você tem um bash que suporta matrizes associativas:

declare -A jobinfo

# collect job information
joblist=( $(jobs -p) )
for pid in "${joblist[@]}"; do
    jobinfo["$pid"]="$( ps -p "$pid" -o args= )"
done

# later...

# wait for jobs
err=0
for pid in "${joblist[@]}"; do
    if ! { wait "$pid" || ! (( code=$? )); }; then
        printf 'Got non-zero exit status (%d) from PID %d: %s\n' \
            "$code" "$pid" "${jobinfo[$pid]}"
        err=1
    fi
done

# exit 0 if all was good, exit 1 otherwise
exit "$err"

Aqui eu coleciono todos os dados necessários antes de começar a esperar que os trabalhos saiam. Também espero que todas as tarefas todas sejam concluídas, para que o usuário obtenha informações sobre não apenas o primeiro trabalho com falha.

Sem usar matrizes associativas (deve funcionar no padrão bash no macOS):

# collect job information
joblist=( $(jobs -p) )
for pid in "${joblist[@]}"; do
    jobinfo+=( "$( ps -p "$pid" -o args= )" )
done

# later...

err=0
i=0
for pid in "${joblist[@]}"; do
    if ! { wait "$pid" || ! (( code=$? )); }; then
        printf 'Got non-zero exit status (%d) from PID %d: %s\n' \
            "$code" "$pid" "${jobinfo[$i]}"
        err=1
    fi

    i=$(( i + 1 ))
done

exit "$err"
    
por 24.03.2018 / 08:48
0

Se o seu sistema operacional (por exemplo, o Linux) tiver um diretório / proc, você poderá obter todas as informações necessárias em / proc / $ PID

for PID in $(jobs -p); do
    dosomethingwith /proc/$PID/ # please take a look at what it contents ;-)
    done
    
por 24.03.2018 / 09:55