GNU/Linux >> Tutoriels Linux >  >> Linux

Comment capturer le statut de retour et utiliser Tee en même temps dans Korn Shell ??

Cette question a déjà des réponses ici  :Obtenir l'état de sortie d'un processus redirigé vers un autre

(16 réponses)
Fermé il y a 7 ans.

Considérez le code source :

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. Enfant.sh

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

Sortie :

Exit status: 1
Exit status: 0
  • Variable $exit_status capture le statut de sortie de Child.sh et est donc 1 .
  • Dans le 2ème cas, $exit_status capture le statut de sortie de tee, qui est .

Alors, comment puis-je capturer le statut de sortie et également utiliser tee ?

Réponse acceptée :

Reproduit (et amélioré) à partir de la FAQ comp.unix.shell (puisque j'ai écrit cette section de la FAQ) :

Comment puis-je obtenir le code de sortie de cmd1 dans cmd1|cmd2

Tout d'abord, notez que le code de sortie cmd1 peut être différent de zéro et ne signifie toujours pas
une erreur. Cela se produit par exemple dans

cmd | head -n 1

vous pouvez observer un état de sortie 141 (ou 269 avec ksh93, ou 397 avec yash) de cmd ,
mais c'est parce que cmd a été interrompu par un signal SIGPIPE lorsque head -n 1 terminé après avoir lu une ligne.

Connaître l'état de sortie des éléments d'un pipeline

cmd1 | cmd2 | cmd3

avec zsh (et fish 3.1+) :

Les codes de sortie sont fournis dans le pipestatus tableau spécial. cmd1 le code de sortie est dans $pipestatus[1] , cmd3 code de sortie dans $pipestatus[3] , de sorte que $status /$? est toujours le même que $pipestatus[-1] .

avec bash :

Les codes de sortie sont fournis dans le PIPESTATUS tableau spécial. cmd1 le code de sortie est dans ${PIPESTATUS[0]} , cmd3 code de sortie dans ${PIPESTATUS[2]} , de sorte que $? est toujours identique à ${PIPESTATUS[-1]} (ou ${PIPESTATUS[@]: -1} pour les versions antérieures à 4.2).

avec n'importe quel autre obus de type Bourne

Vous devez utiliser une astuce pour transmettre les codes de sortie au shell principal. Vous pouvez le faire
en utilisant un pipe(2). Au lieu d'exécuter cmd1 , vous exécutez cmd1; echo "$?" et assurez-vous que $ ? fait son chemin vers le 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"

Codes de sortie dans $ec1 , $ec2 , $ec3 .

avec un shell POSIX

Vous pouvez utiliser cette fonction pour vous faciliter la tâche :

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

Utilisez-le comme :

run cmd1 | cmd2 | cmd3

les codes de sortie sont dans $pipestatus_1 , $pipestatus_2 , $pipestatus_3 et $? est le statut de sortie non nul le plus à droite (comme avec le pipefail option de certains obus).

Connexe :Récupérer des fichiers supprimés accidentellement ?
Linux
  1. Comment utiliser la commande Linux Touch + Exemples

  2. Comment créer un alias et utiliser la commande Alias ​​sous Linux

  3. Comment copier des fichiers et changer la propriété, les autorisations en même temps

  4. Bash + Comment quitter le script secondaire et le script principal à chaque fois ?

  5. Comment installer et utiliser la commande Ping sous Linux

Comment utiliser la commande Linux ftp pour charger et télécharger des fichiers sur le shell

Comment installer et utiliser ZSH Shell sous Linux

Comment installer et utiliser Nu Shell sous Linux

Linux perf :comment utiliser la commande et le profileur

Android - Comment puis-je utiliser les commandes shell et interagir avec le système Linux en dessous ?

En quoi le temps CPU et l'utilisation du CPU sont-ils identiques ?