J'essaie de faire écho à la dernière commande exécutée à l'intérieur d'un script bash. J'ai trouvé un moyen de le faire avec des history,tail,head,sed
ce qui fonctionne bien lorsque les commandes représentent une ligne spécifique dans mon script du point de vue de l'analyseur. Cependant, dans certaines circonstances, je n'obtiens pas la sortie attendue, par exemple lorsque la commande est insérée à l'intérieur d'un fichier case
déclaration :
Le script :
#!/bin/bash
set -o history
date
last=$(echo `history |tail -n2 |head -n1` | sed 's/[0-9]* //')
echo "last command is [$last]"
case "1" in
"1")
date
last=$(echo `history |tail -n2 |head -n1` | sed 's/[0-9]* //')
echo "last command is [$last]"
;;
esac
Le résultat :
Tue May 24 12:36:04 CEST 2011
last command is [date]
Tue May 24 12:36:04 CEST 2011
last command is [echo "last command is [$last]"]
[Q] Quelqu'un peut-il m'aider à trouver un moyen de faire écho à la dernière commande exécutée indépendamment de la façon dont/où cette commande est appelée dans le script de bash ?
Ma réponse
Malgré les contributions très appréciées de mes collègues du SO, j'ai opté pour la rédaction d'une run
qui exécute tous ses paramètres comme une seule commande et affiche la commande et son code d'erreur en cas d'échec - avec les avantages suivants :
-Il suffit de faire précéder les commandes que je veux vérifier de la mention run
ce qui les garde sur une seule ligne et n'affecte pas la concision de mon script.
-Lorsque le script échoue sur l'une de ces commandes, la dernière ligne de sortie de mon script est un message qui affiche clairement quelle commande a échoué ainsi que son code de sortie, ce qui facilite le débogage.
Exemple script :
#!/bin/bash
die() { echo >&2 -e "\nERROR: $@\n"; exit 1; }
run() { "$@"; code=$?; [ $code -ne 0 ] && die "command [$*] failed with error code $code"; }
case "1" in
"1")
run ls /opt
run ls /wrong-dir
;;
esac
Le résultat :
$ ./test.sh
apacheds google iptables
ls: cannot access /wrong-dir: No such file or directory
ERROR: command [ls /wrong-dir] failed with error code 2
J'ai testé diverses commandes avec des arguments multiples, des variables bash en tant qu'arguments, des arguments entre guillemets... et le résultat est le suivant run
ne les a pas cassés. Le seul problème que j'ai trouvé jusqu'à présent est de lancer un écho qui se casse, mais je ne prévois pas de vérifier mes échos de toute façon.
1 votes
+1, idée brillante ! Notez cependant que
run()
ne fonctionne pas correctement lorsque des guillemets sont utilisés, par exemple ceci échoue :run ssh-keygen -t rsa -C info@example.org -f ./id_rsa -N ""
.0 votes
@johndodo : cela pourrait être corrigé : il suffit de changer
"something"
dans les discussions avec'"something"'
(ou, plutôt,"'something'"
pour permettresomething
(ex : variables) à interpréter/évaluer au premier niveau, si nécessaire)2 votes
J'ai changé l'erreur
run() { $*; … }
en une version plus proche de la réalitérun() { "$@"; … }
parce que la réponse erronée a fini par donner la questioncp
se termine avec un statut d'erreur de 64 où le problème était que le$*
a cassé les arguments de la commande au niveau des espaces dans les noms, mais"$@"
ne le ferait pas.0 votes
Question connexe sur Unix StackExchange : unix.stackexchange.com/questions/21930/
0 votes
last=$(history | tail -n1 | sed 's/^[[:space:]][0-9]*[[:space:]]*//g')
a mieux fonctionné, du moins pour zsh et macOS 10.110 votes
fc -nl -1
d'ici fonctionne aussi bien et est beaucoup plus simple