83 votes

Écriture de try catch finally dans un shell

Est-ce qu'il existe une commande linux bash comme la commande java try catch finally ? Ou est-ce que le shell linux continue toujours ?

try {
   `executeCommandWhichCanFail`
   mv output
} catch {
    mv log
} finally {
    rm tmp
}

135voto

user2661977 Points 81

D'après votre exemple, il semble que vous essayez de faire quelque chose qui s'apparente à la suppression systématique d'un fichier temporaire, indépendamment de la façon dont un script se termine. En Bash, pour ce faire, essayez l'option trap pour piéger le EXIT signal.

#!/bin/bash

trap 'rm tmp' EXIT

if executeCommandWhichCanFail; then
    mv output
else
    mv log
    exit 1 #Exit with failure
fi

exit 0 #Exit with success

En rm tmp dans la déclaration trap est toujours exécuté lorsque le script se termine, de sorte que le fichier "tmp" tentera toujours d'être supprimé.

Les pièges installés peuvent également être réinitialisés ; un appel à trap avec seulement un nom de signal réinitialisera le gestionnaire de signal.

trap EXIT

Pour plus de détails, voir la page de manuel de bash : man bash

110voto

Faiz Points 8115

En quelque sorte :

{ # your 'try' block
    executeCommandWhichCanFail &&
    mv output
} || { # your 'catch' block
    mv log
}

 rm tmp # finally: this will always happen

2voto

DogeCode Points 141

J'ai réussi à utiliser cette syntaxe dans mon script :

# Try, catch, finally
(echo "try this") && (echo "and this") || echo "this is the catch statement!"

# this is the 'finally' statement
echo "finally this"

Si l'une ou l'autre des instructions "try" génère une erreur ou se termine par exit 1 L'interprète passe ensuite à l'instruction catch, puis à l'instruction finally.

Si les deux instructions try réussissent (et/ou se terminent par exit ), l'interpréteur ignore l'instruction catch et exécute l'instruction finally.

Exemple_1 :

goodFunction1(){
  # this function works great
  echo "success1"
}

goodFunction2(){
  # this function works great
  echo "success2"
  exit
}

(goodFunction1) && (goodFunction2) || echo "Oops, that didn't work!"

echo "Now this happens!"

Sortie_1

success1
success2
Now this happens!

Exemple _2

functionThrowsErr(){
  # this function returns an error
  ech "halp meh"
}

goodFunction2(){
  # this function works great
  echo "success2"
  exit
}

(functionThrowsErr) && (goodFunction2) || echo "Oops, that didn't work!"

echo "Now this happens!"

Sortie_2

main.sh: line 3: ech: command not found
Oops, that didn't work!
Now this happens!

Exemple_3

functionThrowsErr(){
  # this function returns an error
  echo "halp meh"
  exit 1
}

goodFunction2(){
  # this function works great
  echo "success2"
}

(functionThrowsErr) && (goodFunction2) || echo "Oops, that didn't work!"

echo "Now this happens!"

Sortie_3

halp meh
Oops, that didn't work!
Now this happens!

Notez que l'ordre des fonctions a une incidence sur le résultat. Si vous avez besoin que les deux instructions soient essayées et capturées séparément, utilisez deux instructions try catch.

(functionThrowsErr) || echo "Oops, functionThrowsErr didn't work!"
(goodFunction2) || echo "Oops, good function is bad"

echo "Now this happens!"

Sortie

halp meh
Oops, functionThrowsErr didn't work!
success2
Now this happens!

1voto

user1728219 Points 96

mv prend deux paramètres, il se peut donc que vous vouliez vraiment cat le contenu du fichier de sortie :

echo `{ execCommand && cat output ; } || cat log`
rm -f tmp

0voto

Une autre façon de procéder serait la suivante :

set -e;  # stop on errors

mkdir -p "$HOME/tmp/whatevs"

exit_code=0

(
  set +e;
  (
    set -e;
    echo 'foo'
    echo 'bar'
    echo 'biz'
  )
  exit_code="$?"
)

rm -rf "$HOME/tmp/whatevs"

if [[ "exit_code" != '0' ]]; then
   echo 'failed';
fi 

bien que ce qui précède n'offre pas vraiment d'avantages par rapport à ce qui précède :

set -e;  # stop on errors

mkdir -p "$HOME/tmp/whatevs"

exit_code=0

(
    set -e;
    echo 'foo'
    echo 'bar'
    echo 'biz'
    exit 44;
    exit 43;

) || {
   exit_code="$?"  # exit code of last command which is 44
}

rm -rf "$HOME/tmp/whatevs"

if [[ "exit_code" != '0' ]]; then
   echo 'failed';
fi

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X