Discriminar entre subcasters CHLD na função de armadilha

3

Eu tenho este script bash:

#!/usr/bin/env bash

set -m          # allow for job control
EXIT_CODE=0     # exit code of overall script

function foo() {
   echo "CHLD pid is $!"   # doesn't seem to be the expected pid
   echo "CHLD exit code is $?"  #exit code seems to pertain to some other process
   if [[ $? > 0 ]]; then
      echo "at least one test failed"
      EXIT_CODE=1
   fi
}

trap 'foo' CHLD

DIRN=$(dirname "$0")

commands=(
    "echo 'foo'; exit 1;"
    "echo 'bar'; exit 0;"
    "echo 'baz'; exit 2;"
)

clen='expr "${#commands[@]}" - 1' # get length of commands - 1

for i in 'seq 0 "$clen"'; do
    (echo "${commands[$i]}" | bash) &   # run the command via bash in subshell
    echo "$i ith command has been issued as a background job"
done

# wait for all to finish
wait

echo "EXIT_CODE => $EXIT_CODE"
exit "$EXIT_CODE"

Múltiplos subshells saem e disparam a função foo ao sair. Eu teria esperado apenas 3 eventos CHLD capturados pela função foo, mas há pelo menos 6.

Como posso discriminar entre os eventos CHLD que aparecem na função foo ?

Por exemplo, aqui está a saída do script acima:

CHLD exit code is 0
CHLD exit code is 0
CHLD exit code is 0
0 ith command has been issued as a background job
1 ith command has been issued as a background job
2 ith command has been issued as a background job
bar
baz
foo
CHLD exit code is 0
CHLD exit code is 0
CHLD exit code is 0
EXIT_CODE => 0

Como você pode ver, há 6 CHLD events; mas eu realmente me preocupo com 3. Além disso, eu deveria estar vendo 1,0,2 como códigos de saída, não 0,0,0.

Então eu tenho duas perguntas:

  1. Existe uma maneira de identificar qual sub-linha está saindo na função foo?
  2. Por que estou vendo 0 para o código de saída, quando deveria ser 1 ou 2?
por Alexander Mills 13.02.2017 / 10:50

1 resposta

2

Não sei por que os valores $? e $! na função foo não pertencem ao CHLD em questão, mas as seguintes correções parecem contornar o problema, usando jobs -p dentro a função foo , assim:

#!/usr/bin/env bash

set -m          # allow for job control
EXIT_CODE=0     # exit code of overall script

function foo() {
    for job in 'jobs -p'; do
        echo "PID => ${job}"
        if ! wait ${job} ; then
            echo "At least one test failed with exit code => $?" ;
            EXIT_CODE=1;
        fi
    done
}

trap 'foo' CHLD

DIRN=$(dirname "$0")

commands=(
    "{ echo 'foo' && exit 4; }"
    "{ echo 'bar' && exit 3; }"
    "{ echo 'baz' && exit 5; }"
)

clen='expr "${#commands[@]}" - 1' # get length of commands - 1

for i in 'seq 0 "$clen"'; do
    (echo "${commands[$i]}" | bash) &   # run the command via bash in subshell
    echo "$i ith command has been issued as a background job"
done

wait       # wait for all to finish

echo "EXIT_CODE => $EXIT_CODE"
exit "$EXIT_CODE"
    
por 13.02.2017 / 11:43