Während ein aliaseine Möglichkeit , es zu tun ist, dies kann mit gemacht werden evalals auch - es ist nur , dass Sie nicht so viel wollen Sie evaldie Befehlsausführung , wie Sie mögen evalden Befehl Erklärung .
Ich mag aliases - ich benutze sie die ganze Zeit, aber ich mag Funktionen besser - insbesondere ihre Fähigkeit, mit Parametern umzugehen, und dass sie nicht unbedingt in der Befehlsposition erweitert werden müssen, wie es für aliases erforderlich ist .
Also dachte ich, vielleicht möchten Sie das auch versuchen:
_time() if set -- "${IFS+IFS=\$2;}" "$IFS" "$@" && IFS='
'; then set -- "$1" "$2" "$*"; unset IFS
eval "$1 $TIME ${3#"$1"?"$2"?}"
fi
Das $IFSbisschen geht hauptsächlich um $*. Es ist wichtig , dass das ( subshell bit )ist auch das Ergebnis einer Shell - Erweiterung und so um die Argumente in einen parsable String I Gebrauch zu erweitern "$*" (nicht eval "$@", nebenbei gesagt, es sei denn , Sie sind sie sicher alle der args auf Räume verbunden werden) . Das geteilte Trennzeichen zwischen args in "$*"ist das erste Byte in $IFS, und daher kann es gefährlich sein, fortzufahren, ohne seinen Wert sicherzustellen. So ist die Funktion speichert $IFS, setzt er auf eine \nlange genug ewline zu set ... "$*"in "$3", unsetes s, dann wird ihr Wert setzt , wenn sie zuvor einen hatte.
Hier ist eine kleine Demo:
TIME='set -x; time'
_time \( 'echo "$(echo any number of subshells)"' \
'command -V time' \
'hash time' \
\) 'set +x'
Sie sehen, ich habe zwei Befehle in den Wert von $TIMEdort eingefügt - jede Zahl ist in Ordnung - sogar keine -, aber stellen Sie sicher, dass sie maskiert und richtig zitiert wird - und dasselbe gilt für die Argumente dazu _time(). Sie werden alle bei ihrer Ausführung zu einer einzigen Befehlszeichenfolge verkettet - aber jedes \nArgument erhält seine eigene Ewline und kann daher relativ einfach verteilt werden. Oder Sie können sie alle in einem zusammenfassen, wenn Sie \nmöchten , und sie in Ewlines oder Semikolons oder was-haben-Sie trennen . Stellen Sie nur sicher, dass ein einzelnes Argument einen Befehl darstellt, den Sie beim Aufrufen in einem Skript in eine eigene Zeile einfügen möchten. \(Zum Beispiel ist in Ordnung, solange es schließlich mit folgt \). Grundsätzlich das normale Zeug.
Wenn evaldas obige Snippet gefüttert wird, sieht es so aus:
+ eval 'IFS=$2;set -x; time (
echo "$(echo any number of subshells)"
command -V time
hash time
)
set +x'
Und die Ergebnisse sehen aus wie ...
AUSGABE
+++ 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
Der hashFehler zeigt an, dass ich keine /usr/bin/timeinstalliert habe (weil ich keine habe) und commandlässt uns wissen, welche Zeit läuft. Das Trailing set +xist ein weiterer Befehl, der nach ausgeführt wird time (was möglich ist). Es ist wichtig, bei Eingabebefehlen vorsichtig zu sein, wenn evalSie etwas eingeben .