Mentre un aliasè un modo per farlo, questo può essere fatto anche con eval- è solo che non vuoi tanto eseguire evall'esecuzione del comando quanto vuoi evalla dichiarazione del comando .
Mi piace aliases - li uso sempre, ma mi piacciono le funzioni meglio - specialmente la loro capacità di gestire i parametri e che non devono necessariamente essere espansi nella posizione di comando come richiesto per aliases.
Quindi ho pensato che forse avresti voluto provare anche questo:
_time() if set -- "${IFS+IFS=\$2;}" "$IFS" "$@" && IFS='
'; then set -- "$1" "$2" "$*"; unset IFS
eval "$1 $TIME ${3#"$1"?"$2"?}"
fi
La parte $IFSriguarda principalmente $*. È importante che ( subshell bit )sia anche il risultato di un'espansione della shell e quindi per espandere gli argomenti in una stringa analizzabile che uso "$*" (non eval "$@", a proposito, a meno che tu non sia sicuro che tutti gli arg possano essere uniti su spazi) . Il delimitatore diviso tra args in "$*"è il primo byte in $IFS, quindi potrebbe essere pericoloso procedere senza accertarne il valore. Quindi la funzione salva $IFS, lo imposta a un \newline abbastanza a lungo da set ... "$*"dentro "$3", unsetè tutto, quindi resetta il suo valore, se in precedenza aveva uno.
Ecco una piccola demo:
TIME='set -x; time'
_time \( 'echo "$(echo any number of subshells)"' \
'command -V time' \
'hash time' \
\) 'set +x'
Vedete, ho messo due comandi nel valore di $TIMElì - ogni numero va bene - anche nessuno - ma assicuratevi che sia evitato e citato correttamente - e lo stesso vale per gli argomenti _time(). Saranno tutti concatenati in una singola stringa di comando quando vengono eseguiti, ma ogni arg ottiene la sua \newline e quindi possono essere distribuiti relativamente facilmente. Altrimenti puoi raggrupparli tutti in uno, se vuoi, e separarli su \newline o semi-due punti o what-have-you. Assicurati solo che un singolo argomento rappresenti un comando che ti sentiresti a tuo agio nel mettere la propria linea in uno script quando lo chiami. \(, ad esempio, va bene, purché alla fine venga seguito da \). Fondamentalmente le cose normali.
Quando evalviene alimentato lo snippet precedente, sembra che:
+ eval 'IFS=$2;set -x; time (
echo "$(echo any number of subshells)"
command -V time
hash time
)
set +x'
E i suoi risultati sembrano ...
PRODUZIONE
+++ echo any number of subshells
++ echo 'any number of subshells'
any number of subshells
++ command -V time
time is a shell keyword
++ hash time
bash: hash: time: not found
real 0m0.003s
user 0m0.000s
sys 0m0.000s
++ set +x
L' hasherrore indica che non ho /usr/bin/timeinstallato (perché non lo faccio) e commandfacci sapere a che ora è in esecuzione. Il trailing set +xè un altro comando eseguito dopo time (che è possibile) - è importante fare attenzione con i comandi di input quando si evalesegue qualcosa.