GNU/Linux >> Linux Esercitazione >  >> Linux

Come acquisire lo stato del reso e utilizzare la maglietta allo stesso tempo in Korn Shell?

Questa domanda ha già risposte qui :Ottieni lo stato di uscita del processo che viene reindirizzato a un altro

(16 risposte)
Chiuso 7 anni fa.

Considera il codice sorgente:

1. Genitore.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. Child.sh

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

Risultato:

Exit status: 1
Exit status: 0
  • Variabile $exit_status sta acquisendo lo stato di uscita di Child.sh, così come 1 .
  • Nel 2° caso, $exit_status sta acquisendo lo stato di uscita di tee, che è .

Quindi, come posso acquisire lo stato di uscita e utilizzare anche tee?

Risposta accettata:

Riprodotto (e migliorato) dalle FAQ di comp.unix.shell (dato che ho scritto quella sezione delle FAQ):

Come ottengo il codice di uscita di cmd1 in cmd1|cmd2

Innanzitutto, tieni presente che il codice di uscita cmd1 potrebbe essere diverso da zero e comunque non
significa un errore. Questo accade ad esempio in

cmd | head -n 1

potresti osservare uno stato di uscita 141 (o 269 con ksh93 o 397 con yash) di cmd ,
ma è perché cmd è stato interrotto da un segnale SIGPIPE quando head -n 1 terminato dopo aver letto una riga.

Per conoscere lo stato di uscita degli elementi di una pipeline

cmd1 | cmd2 | cmd3

con zsh (e fish 3.1+):

I codici di uscita sono forniti in pipestatus matrice speciale. cmd1 il codice di uscita è in $pipestatus[1] , cmd3 codice di uscita in $pipestatus[3] , in modo che $status /$? è sempre lo stesso di $pipestatus[-1] .

con bash:

I codici di uscita sono forniti nel PIPESTATUS matrice speciale. cmd1 il codice di uscita è in ${PIPESTATUS[0]} , cmd3 codice di uscita in ${PIPESTATUS[2]} , quindi $? è sempre uguale a ${PIPESTATUS[-1]} (o ${PIPESTATUS[@]: -1} per versioni precedenti alla 4.2).

con qualsiasi altro tipo di shell Bourne

Devi usare un trucco per passare i codici di uscita alla shell principale. Puoi farlo
usando una pipe(2). Invece di eseguire cmd1 , esegui cmd1; echo "$?" e assicurati
$? si fa strada verso la shell.

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"

Codici di uscita in $ec1 , $ec2 , $ec3 .

con una shell POSIX

Puoi utilizzare questa funzione per semplificare:

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"
}

Usalo come:

run cmd1 | cmd2 | cmd3

i codici di uscita sono in $pipestatus_1 , $pipestatus_2 , $pipestatus_3 e $? è lo stato di uscita diverso da zero più a destra (come con pipefail opzione di alcune shell).

Correlati:Recupero di file eliminati accidentalmente?
Linux
  1. Come utilizzare il comando touch di Linux + esempi

  2. Come creare un alias e utilizzare il comando alias in Linux

  3. Come posso utilizzare i comandi watch e jobs insieme in Bash?

  4. Copia e chmod/chown allo stesso tempo

  5. Ping e tcpdump allo stesso tempo

Come utilizzare il comando ftp di Linux per caricare e scaricare file sulla shell

Come installare e utilizzare ZSH Shell in Linux

Come installare e utilizzare Nu Shell su Linux

Linux perf:come utilizzare il comando e il profiler

Android - Come posso utilizzare i comandi della shell e interagire con il sistema Linux sottostante?

In che modo il tempo della CPU e l'utilizzo della CPU sono uguali?