esperar a que el proceso en proceso devuelva un código de salida incorrecto

esperar a que el proceso en proceso devuelva un código de salida incorrecto

Debe faltarme algo aquí:

#!/bin/bash
timeout 5 sleep 10 &
parent_pid=$( ps --pid $! -o ppid --no-headers )
timeout_pid=$( pgrep --parent $parent_pid timeout )
wait $timeout_pid
echo "exit code: $?"

Llame al script wait-pidy ejecute:

$ ./wait-pid 
exit code: 124

que es lo que esperaba, timeoutfinaliza el sleepproceso y sale con 124, que waitregresa obedientemente.

Pero si agrego una canalización al comando inicial:

timeout 5 sleep 10 | cat &
parent_pid=$( ps --pid $! -o ppid --no-headers )
timeout_pid=$( pgrep --parent $parent_pid timeout )
wait $timeout_pid
echo "exit code: $?"

ahora me sale:

$ ./wait-pid 
exit code: 0

Aún no debería waitdevolver el código de salida del proceso que está esperando: timeout. Entonces, ¿el código de salida no debería seguir siendo 124?

Esto es con la versión bash 4.4.20(1).

Respuesta1

Recibí una respuesta del experto Greg Woolge en la lista de correo de bash. El elemento clave es:

El comando de espera solo funciona en procesos secundarios directos del shell, también conocidos como "comandos asíncronos". En el caso de que su comando asincrónico sea una canalización, recurriremos al conjunto de características sh original. El estado de salida de su comando asincrónico es el del último comando en la canalización, y los estados de salida de los otros comandos simplemente se descartan.

Es por eso que no obtengo el código de salida de timeoutcuando está en una tubería.

La forma de obtener el comportamiento que deseo es utilizar un archivo temporal para capturar códigos de salida desde el código asincrónico. Algo como:

{
  timeout 5 sleep 10 | cat
  echo "${PIPESTATUS[@]}" > "$tempfile"
} &
wait

información relacionada