GNU/Linux >> Tutoriales Linux >  >> Linux

¿Cómo capturar el estado de devolución y usar Tee al mismo tiempo en Korn Shell?

Esta pregunta ya tiene respuestas aquí :Obtenga el estado de salida del proceso que se canaliza a otro

(16 respuestas)
Cerrado hace 7 años.

Considere el código fuente:

1. Padre.sh

#!/usr/bin/ksh
# No tee
ksh Child.sh;
exit_status=$?;
echo "Exit status: ${exit_status}"
# Using tee
ksh Child.sh | tee -a log.txt;
exit_status=$?;
echo "Exit status: ${exit_status}"

2. Niño.sh

#!/usr/bin/ksh
...
exit 1;

Salida:

Exit status: 1
Exit status: 0
  • Variable $exit_status está capturando el estado de salida de Child.sh y también 1 .
  • En el segundo caso, $exit_status está capturando el estado de salida de tee, que es .

Entonces, ¿cómo capturo el estado de salida y también uso tee?

Respuesta aceptada:

Reproducido (y mejorado) de las preguntas frecuentes de comp.unix.shell (ya que yo escribí esa sección de las preguntas frecuentes):

¿Cómo obtengo el código de salida de cmd1 en cmd1|cmd2

?

Primero, tenga en cuenta que el código de salida de cmd1 podría ser distinto de cero y aun así no
significar un error. Esto sucede, por ejemplo, en

cmd | head -n 1

puede observar un estado de salida 141 (o 269 con ksh93, o 397 con yash) de cmd ,
pero es porque cmd fue interrumpido por una señal SIGPIPE cuando head -n 1 terminado después de haber leído una línea.

Para conocer el estado de salida de los elementos de un pipeline

cmd1 | cmd2 | cmd3

con zsh (y fish 3.1+):

Los códigos de salida se proporcionan en el pipestatus matriz especial. cmd1 el código de salida está en $pipestatus[1] , cmd3 código de salida en $pipestatus[3] , de modo que $status /$? siempre es igual a $pipestatus[-1] .

con bash:

Los códigos de salida se proporcionan en el PIPESTATUS matriz especial. cmd1 el código de salida está en ${PIPESTATUS[0]} , cmd3 código de salida en ${PIPESTATUS[2]} , por lo que $? siempre es igual a ${PIPESTATUS[-1]} (o ${PIPESTATUS[@]: -1} para versiones anteriores a la 4.2).

con cualquier otro proyectil tipo Bourne

Necesita usar un truco para pasar los códigos de salida al shell principal. Puedes hacerlo
usando una tubería(2). En lugar de ejecutar cmd1 , ejecuta cmd1; echo "$?" y asegúrese de
$? se dirige al caparazón.

exec 3>&1
code=`
  # now, inside the backticks, fd4 goes to the pipe
  # whose other end is read and stored in $code  for
  # later evaluation; fd1 is the normal standard output
  # preserved the line before with exec 3>&1

  exec 4>&1 >&3 3>&- 
  {
    cmd1 4>&-; echo "ec1=$?;" >&4
  } | {
    cmd2 4>&-; echo "ec2=$?;" >&4
  } | cmd3 4>&-
  echo "ec3=$?;" >&4
`
exec 3>&-
eval "$code"

Códigos de salida en $ec1 , $ec2 , $ec3 .

con un shell POSIX

Puedes usar esta función para hacerlo más fácil:

run() {
  j=1
  while eval "${pipestatus_$j+:} false"; do
    unset "pipestatus_$j"
    j=$(($j+1))
  done
  j=1 com= k=1 l=
  for arg do
    case $arg in
      ('|')
        com="$com {
               $l "'3>&-
               echo "pipestatus_'$j'=$?" >&3
             } 4>&- |'
        j=$(($j+1)) l=;;
      (*)
        l="$l "${$k}""
    esac
    k=$(($k+1))
  done
  com="$com $l"' 3>&- >&4 4>&-
       echo "pipestatus_'$j'=$?"'

  { eval "$(exec 3>&1; eval "$com")"; } 4>&1
  j=1
  ret=0
  while eval "${pipestatus_$j+:} false"; do
    eval '[ "$pipestatus_'"$j"'" -eq 0 ] || ret=$pipestatus_'"$j"
    j=$(($j+1))
  done
  return "$ret"
}

Úselo como:

run cmd1 | cmd2 | cmd3

los códigos de salida están en $pipestatus_1 , $pipestatus_2 , $pipestatus_3 y $? es el estado de salida distinto de cero más a la derecha (como con el pipefail opción de algunas conchas).

Relacionado:¿Recuperar archivos borrados accidentalmente?
Linux
  1. Cómo crear un alias y usar el comando Alias ​​en Linux

  2. Bash + ¿Cómo salir del script secundario y del script principal en ambas ocasiones?

  3. Cómo obtener el estado de salida de un bucle en bash

  4. ¿Cómo uso los comandos watch y jobs juntos en Bash?

  5. Linux:¿Cómo usar un archivo como entrada y salida al mismo tiempo?

Cómo usar el comando ftp de Linux para cargar y descargar archivos en el shell

Cómo instalar y usar ZSH Shell en Linux

Cómo instalar y usar Nu Shell en Linux

Perf de Linux:cómo usar el comando y el generador de perfiles

Android:¿cómo puedo usar los comandos de shell e interactuar con el sistema Linux que se encuentra debajo?

¿En qué se parecen el tiempo de CPU y el uso de CPU?