GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Wie erfasse ich den Rückgabestatus und verwende Tee gleichzeitig in Korn Shell?

Für diese Frage gibt es hier bereits Antworten :Exit-Status des Prozesses abrufen, der an einen anderen weitergeleitet wird

(16 Antworten)
Vor 7 Jahren geschlossen.

Betrachten Sie den Quellcode:

1. Parent.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;

Ausgabe:

Exit status: 1
Exit status: 0
  • Variable $exit_status erfasst den Exit-Status von Child.sh und 1 ebenfalls .
  • Im zweiten Fall $exit_status erfasst den Exit-Status von tee, also .

Wie erfasse ich also den Exit-Status und verwende auch tee?

Akzeptierte Antwort:

Reproduziert (und verbessert) aus der comp.unix.shell-FAQ (da ich zufällig diesen Abschnitt der FAQ geschrieben habe):

Wie erhalte ich den Exit-Code von cmd1 in cmd1|cmd2

Beachten Sie zunächst, dass der Exit-Code von cmd1 ungleich Null sein kann und dennoch
keinen Fehler bedeutet. Dies geschieht beispielsweise in

cmd | head -n 1

Sie könnten einen 141 (oder 269 mit ksh93 oder 397 mit yash) Exit-Status von cmd beobachten ,
aber es liegt daran, dass cmd wurde durch ein SIGPIPE-Signal unterbrochen, wenn head -n 1 beendet, nachdem eine Zeile gelesen wurde.

Um den Exit-Status der Elemente einer Pipeline zu kennen

cmd1 | cmd2 | cmd3

mit zsh (und fish 3.1+):

Die Exit-Codes werden im pipestatus bereitgestellt spezielles Array. cmd1 Der Exit-Code befindet sich in $pipestatus[1] , cmd3 Exit-Code in $pipestatus[3] , sodass $status /$? ist immer dasselbe wie $pipestatus[-1] .

mit bash:

Die Exit-Codes werden im PIPESTATUS bereitgestellt spezielles Array. cmd1 Exitcode ist in ${PIPESTATUS[0]} , cmd3 Exit-Code in ${PIPESTATUS[2]} , sodass $? ist immer dasselbe wie ${PIPESTATUS[-1]} (oder ${PIPESTATUS[@]: -1} für Versionen älter als 4.2).

mit anderen Bourne-ähnlichen Muscheln

Sie müssen einen Trick anwenden, um die Exit-Codes an die Haupt-Shell zu übergeben. Sie können es
mit einer Pipe(2) machen. Statt cmd1 auszuführen , führen Sie cmd1; echo "$?" und stellen Sie
sicher, dass $? macht sich auf den Weg zur 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"

Exit-Codes in $ec1 , $ec2 , $ec3 .

mit einer POSIX-Shell

Sie können diese Funktion verwenden, um es einfacher zu machen:

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

Verwenden Sie es als:

run cmd1 | cmd2 | cmd3

Exit-Codes befinden sich in $pipestatus_1 , $pipestatus_2 , $pipestatus_3 und $? ist der Exit-Status ganz rechts ungleich Null (wie beim pipefail Option einiger Muscheln).

Verwandte:Versehentlich gelöschte Dateien wiederherstellen?
Linux
  1. So erstellen Sie einen Alias ​​und verwenden den Alias-Befehl in Linux

  2. So kopieren Sie Dateien und ändern gleichzeitig den Besitz und die Berechtigungen

  3. Wie kopiert man eine Datei und erstellt gleichzeitig die Zielverzeichnisse?

  4. So installieren und verwenden Sie den Ping-Befehl unter Linux

  5. So erhalten Sie den Exit-Status in einer Bash-Schleife

So verwenden Sie den Linux-Befehl ftp zum Hoch- und Herunterladen von Dateien auf der Shell

So installieren und verwenden Sie die ZSH-Shell unter Linux

So installieren und verwenden Sie Nu Shell unter Linux

Linux perf:So verwenden Sie den Befehl und den Profiler

Android - Wie kann ich Shell-Befehle verwenden und mit dem darunter liegenden Linux-System interagieren?

Wie sind CPU-Zeit und CPU-Auslastung gleich?