Sto cercando di ripetere l'ultimo comando eseguito all'interno di uno script bash. Ho trovato un modo per farlo con alcuni history,tail,head,sedche funzionano bene quando i comandi rappresentano una riga specifica nel mio script dal punto di vista del parser. Tuttavia in alcune circostanze non ottengo l'output atteso, ad esempio quando il comando viene inserito all'interno di caseun'istruzione:
Il copione:
#!/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
Il risultato:
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]"]
[D] Qualcuno può aiutarmi a trovare un modo per eseguire l'eco dell'ultimo comando eseguito indipendentemente da come / dove viene chiamato questo comando all'interno dello script bash?
La mia risposta
Nonostante i contributi molto apprezzati dai miei colleghi SO, ho optato per la scrittura di una runfunzione - che esegue tutti i suoi parametri come un unico comando e visualizza il comando e il suo codice di errore quando fallisce - con i seguenti vantaggi:
-Devo solo anteponi i comandi che voglio controllare con runche li mantiene su una riga e non influisce sulla concisione del mio script
-Quando lo script fallisce su uno di questi comandi, l'ultima riga di output del mio script è un messaggio che mostra chiaramente quale comando fallisce insieme al suo codice di uscita, il che rende più facile il debug
Script di esempio:
#!/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
Il risultato:
$ ./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
Ho testato vari comandi con più argomenti, variabili bash come argomenti, argomenti tra virgolette ... e la runfunzione non li ha interrotti. L'unico problema che ho riscontrato finora è stato quello di eseguire un eco che si interrompe ma non ho comunque intenzione di controllare i miei echi.
run()non funziona correttamente quando si utilizzano le virgolette, per esempio questo non riesce:run ssh-keygen -t rsa -C info@example.org -f ./id_rsa -N "".