web-dev-qa-db-fra.com

Ignorer des erreurs spécifiques dans un script Shell

J'ai un petit extrait d'un script Shell qui peut générer de nombreuses erreurs. J'ai le script actuellement configuré pour arrêter globalement sur toutes les erreurs. Cependant, j'aimerais que cette petite sous-section soit légèrement différente.

Voici l'extrait de code:

recover database using backup controlfile until cancel || true; 
auto

Je m'attends à ce que cela finisse par générer une erreur "fichier non trouvé". Cependant, j'aimerais continuer à exécuter cette erreur. Pour toute autre erreur, j'aimerais que le script s'arrête.

Quelle serait la meilleure méthode pour y parvenir?

Bash Version 3.00.16

46
Stunt

Afin d'empêcher bash d'ignorer les erreurs pour des commandes spécifiques, vous pouvez dire:

some-arbitrary-command || true

Cela ferait continuer le script. Par exemple, si vous avez le script suivant:

$ cat foo
set -e
echo 1
some-arbitrary-command || true
echo 2

L'exécuter reviendrait:

$ bash foo
1
z: line 3: some-arbitrary-command: command not found
2

En l'absence de || true Dans la ligne de commande, cela aurait produit:

$ bash foo
1
z: line 3: some-arbitrary-command: command not found

Citation de la manuel :

Le shell ne se ferme pas si la commande qui échoue fait partie de la liste de commandes immédiatement après un mot clé while ou until, faisant partie du test dans une instruction if, faisant partie de toute commande exécutée dans une liste && ou || à l'exception de la commande suivant le dernier && ou ||, toute commande d'un pipeline à l'exception de la dernière, ou si l'état de retour de la commande est inversé avec !. Une interruption sur ERR, si elle est définie, est exécutée avant la fermeture du shell.

EDIT: Afin de changer le comportement de telle sorte que l'exécution doit continuer uniquement si l'exécution de some-arbitrary-command A renvoyé file not found Comme une partie de l'erreur, vous pouvez dire:

[[ $(some-arbitrary-command 2>&1) =~ "file not found" ]]

Par exemple, exécutez ce qui suit (aucun fichier nommé MissingFile.txt N’existe):

$ cat foo 
#!/bin/bash
set -u
set -e
foo() {
  rm MissingFile.txt
}
echo 1
[[ $(foo 2>&1) =~ "No such file" ]]
echo 2
$(foo)
echo 3

Cela produit la sortie suivante:

$ bash foo 
1
2
rm: cannot remove `MissingFile.txt': No such file or directory

Notez que echo 2 A été exécuté mais pas echo 3.

98
devnull

Utilisation:

command || :

: est une bash intégrée qui renvoie toujours le succès. Et, comme discuté ci-dessus, || court-circuit afin que le RHS ne soit exécuté que si le LHS échoue (renvoie non nul).

Les suggestions ci-dessus pour utiliser "true" fonctionneront également, mais sont inefficaces car "true" est un programme externe.

21
Chris Cogdon