Während ein alias
eine Möglichkeit , es zu tun ist, dies kann mit gemacht werden eval
als auch - es ist nur , dass Sie nicht so viel wollen Sie eval
die Befehlsausführung , wie Sie mögen eval
den Befehl Erklärung .
Ich mag alias
es - 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 alias
es 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 $IFS
bisschen 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 \n
lange genug ewline zu set ... "$*"
in "$3"
, unset
es 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 $TIME
dort 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 \n
Argument erhält seine eigene Ewline und kann daher relativ einfach verteilt werden. Oder Sie können sie alle in einem zusammenfassen, wenn Sie \n
mö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 eval
das 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 hash
Fehler zeigt an, dass ich keine /usr/bin/time
installiert habe (weil ich keine habe) und command
lässt uns wissen, welche Zeit läuft. Das Trailing set +x
ist ein weiterer Befehl, der nach ausgeführt wird time
(was möglich ist). Es ist wichtig, bei Eingabebefehlen vorsichtig zu sein, wenn eval
Sie etwas eingeben .