Omawiając różnice między /usr/bin/time
wbudowanym shellem (bash i zsh) time
, ktoś wspomniał, że można go użyć \time
jako skrótu /usr/bin/time
.
Najpierw wydawało się to miłym, niewinnym skrótem, ale potem pojawiły się pytania:
- Dlaczego też
t\ime
działa? - Dlaczego
\cd
zmienia katalog, chociaż/usr/bin/cd
¹ tego nie robi?
Oczywiście \foo
nie jest to równoważne $(which foo)
. Pytanie brzmi teraz:
Czy zaobserwowane zachowanie \foo
zarówno w bash, jak i zsh w jakikolwiek sposób jest objęte definicją powłoki POSIX, a jeśli tak, to dlaczego zachowuje się tak jak on?
Przypis 1: /usr/bin/cd
w moim systemie jest
#!/bin/sh
builtin cd "$@"
shell
quoting
posix
time-utility
Jonas Schäfer
źródło
źródło
Odpowiedzi:
t\ime
lub\cd
(lub"tim"e
lub'cd'
lub${-##*}time
i${-+time}
i każda inna kombinacja cytatów i rozwinięć, o których można by pomyśleć, ostatecznie rozwiązałaby się natime
lubcd
), jest: innym sposobem pisaniacd
itime
.Jednak ostatecznie rozwiązałoby to parsowanie i interpretację składni powłoki
cd
lubtime
w późniejszym czasie. W szczególności dzieje się to długo po rozpoznaniu słowa kluczowego powłoki i podstawieniu aliasu .Tak więc, w tym czasie powłoka szuka słów kluczowych w swoim języku, to nie uznając
ti\me
jakotime
słowo kluczowe powłoki. Więc:będą rozpoznawane przez powłokę jako proste polecenie w przeciwieństwie do
time
słowa kluczowego, po którym następuje proste polecenie.Wówczas cytowanie
ti\me
zostanie przetworzone (tutaj odwrotny ukośnik cytujem
znak, który i tak nie wymaga cytowania, znak cytowania jest usuwany, otrzymujesztime
), atime
polecenie byłoby wyszukiwane jak każde inne polecenie (na liście poleceń wbudowanych , funkcje i pliki wykonywalne w$PATH
. Najprawdopodobniej będą/bin/time
tutaj)Bo w języku powłoki
cd
nie macd
słowa kluczowego, tylkocd
wbudowane polecenie (które ma pierwszeństwo przed twoim/usr/bin/cd
). Jeśli jednak zdefiniujesz aliascd
(podobnyalias cd=pushd
), to samo ponownie. Ponieważ podstawianie aliasów odbywa się bardzo wcześnie, przed usunięciem cytatu, jeśli masz alias dla,cd
a nie jeden dla\cd
(zauważ, że niewiele powłok pozwala na aliasy z odwrotnymi ukośnikami), a następnie pisz:upewniasz się, że Twój
cd
alias nie jest podstawiony.W skrócie, podając nazwę polecenia lub jakiejkolwiek jego części uniemożliwia postrzegane jako słowo kluczowe powłoki (słowa kluczowe są takie rzeczy jak
while
,for
,if
,{
...time
jest to słowo kluczowe w niektórych tylko muszli), a omija aliasu może masz dla niego .Jednak nie zmusza tego polecenia do przetworzenia pliku wykonywalnego
$PATH
, polecenie jest nadal wyszukiwane najpierw wśród funkcji (które można obejść, wykonująccommand time cmd...
) i wbudowanych (które można obejść, wykonującenv time cmd...
, chociaż nie wiem o powłoka, która ma wbudowanetime
polecenie).Zauważ, że cytowanie może również wpływać na zachowanie specjalnych wbudowań rodziny
typeset
/declare
/export
/local
... w niektórych powłokach. Zobacz: Czy do przypisania zmiennych lokalnych potrzebne są oferty? dla szczegółów.źródło
time
icd
która prowadzi do różnicy w obserwowanym zachowaniem jest to, żetime
jest to słowo kluczowe icd
to polecenie wbudowane ?time
jest słowo kluczowe, acd
nie jest. (a jeśli masz alias dlacd
lubtime
, to będzie inna sprawa). Tocd
jest wbudowane lub nie ma w tym momencie żadnego wpływu (jeśli chodzi o wpływ cytowania). Niektóre powłoki mają jednak kilka wbudowanych plików, które znajdują się w połowie drogi między słowami kluczowymi a wbudowanymi, ponieważ ich parsowanie odbywa się inaczej niż w przypadku innych wbudowanych. Tak jest w przypadkuexport
/typeset
/declare
. Powinienem chyba dodać notatkę na ten temat w tej odpowiedzi.