Chociaż jest aliasto jeden ze sposobów, można to zrobić evalrównież za pomocą - po prostu nie tyle chcesz evalwykonania polecenia, ile chceszeval deklaracji polecenia .
podoba mi się alias es - używam ich cały czas, ale bardziej lubię funkcje - szczególnie ich zdolność do obsługi parametrów i że niekoniecznie muszą być one rozszerzane w pozycji poleceń, jak jest to wymagane dla aliases.
Pomyślałem więc, że może też chcesz spróbować:
_time() if set -- "${IFS+IFS=\$2;}" "$IFS" "$@" && IFS='
'; then set -- "$1" "$2" "$*"; unset IFS
eval "$1 $TIME ${3#"$1"?"$2"?}"
fi
Chodzi $IFSgłównie o to $*. Ważne jest, aby wynik ( subshell bit )był również wynikiem rozszerzenia powłoki, a więc w celu rozwinięcia argumentów w parsowalny ciąg, którego używam "$*" (nie eval "$@", nawiasem mówiąc, chyba że jesteś pewien, że wszystkie argumenty można połączyć spacjami) . Rozdzielony separator między argumentami "$*"jest pierwszym bajtem wejściowym $IFS, więc kontynuowanie pracy bez pewności co do jej wartości może być niebezpieczne. Tak więc funkcja zapisuje $IFS, ustawia ją na \newline wystarczająco długo, aby set ... "$*"w "$3", unsets, a następnie resetuje swoją wartość, jeśli wcześniej miała taką.
Oto małe demo:
TIME='set -x; time'
_time \( 'echo "$(echo any number of subshells)"' \
'command -V time' \
'hash time' \
\) 'set +x'
Widzisz, umieściłem w poleceniu dwie wartości $TIME- dowolna liczba jest w porządku - nawet żadna - ale upewnij się, że została poprawnie zmieniona i zacytowana - i to samo dotyczy argumentów _time(). Wszystkie zostaną połączone w jeden ciąg komend, gdy zostaną wykonane - ale każdy argument otrzymuje własny \newline, dzięki czemu można je stosunkowo łatwo rozłożyć. W przeciwnym razie możesz zebrać je wszystkie w jednym, jeśli chcesz, i rozdzielić je na \newline lub średniki lub co tam masz. Po prostu upewnij się, że pojedynczy argument reprezentuje polecenie, które możesz swobodnie umieścić w swoim wierszu w skrypcie podczas jego wywoływania.\(, na przykład jest w porządku, o ile w końcu zostanie zastosowane \). Zasadniczo normalne rzeczy.
Po evalotrzymaniu powyższego fragmentu wygląda on następująco:
+ eval 'IFS=$2;set -x; time (
echo "$(echo any number of subshells)"
command -V time
hash time
)
set +x'
A jego wyniki wyglądają jak ...
WYNIK
+++ 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
hashBłąd wskazuje, że nie masz /usr/bin/timezainstalowanego (bo nie) i commandniech nas nie wie czym jest uruchomiony. Trailing set +xjest kolejną komendą wykonywaną po time (co jest możliwe) - ważne jest, aby zachować ostrożność przy komendach wejściowych podczas evalpisania czegokolwiek.