Wydaje się, że istnieje pewna niespójność, której nie jestem w stanie zrozumieć odnośnie powłoki bash.
Jeśli wykonam:
ls;date;time
wyniki trzech zapytań są pokazane kolejno.
Jednak przy zmianie pozycji daty i godziny pojawia się komunikat o błędzie.
Więc jeśli wykonam:
ls;time;date
komunikat o błędzie mówi: bash: syntax error near unexpected token 'date'
.
Czy ktoś może to wyjaśnić?
time;date
żywodate;time
. Wydaje się, że jest to problem z wejściem do potokubash
i ostatnim char generowanym ztime
wyjściem. Testowane wyniki w różnych emulatorach terminali to: - [Bash] $ data; godzina # [OK] $ godzina; data # [ NotOK ] bash: błąd składni w pobliżu nieoczekiwanego tokena `data '$ czas # tylko błąd nie pojawia się, że jest to wynik dowolnej daty. - [Csh] $ data; godzina # [OK] $ godzina; data # [OK] - [Tcsh] $ data; godzina # [OK] $ godzina; data # [OK] - [Ksh] $ data; godzina # [ OK] $ godzina; data # [OK]Odpowiedzi:
time
Komenda w rurociągu nie jest/usr/bin/time
binarny, ale bashtime
wbudowanej. Porównajman time
zhelp time
. Widoczny błąd polega na tym, że bash nie analizujetime
argumentu. To musi być obecne lub być nowym wierszem. Jest to nowy wiersz w twoim pierwszym przykładzie, ale nieobecny w drugim.Z drugiej strony, jeśli miałbyś biec
lub
gdzie cytaty wokół
'time'
odwołują swój status słowa zarezerwowanego, wtedy bash nie ma problemów z analizą wiersza. Teraz analizuje trzy polecenia na liście, które wykona kolejno i/usr/bin/time
w obu przypadkach zgłosi błąd użycia.Uzupełnienie
Zaobserwowano, że chociaż
time ; date
daje błąd,time ; ; date
nie robi. Prawdopodobnym wyjaśnieniem jest to, żetime ;
interpretacja bash jest równoznaczna ztime <newline>
. Wyrażenietime ; ; date
jest następnie analizowane jako listatime ;
idate
.Jest to zgodne z obserwacją, że
time ;
itime ; ;
są zgodne z prawem, a także, druga jest analizowany jako listy jednoelementowy zawierajtime ;
następnie opcjonalnego średnikiem dozwolony po listach.Tak więc innym sposobem wyjaśnienia, dlaczego pojawia się
time ; date
błąd,bash: syntax error near unexpected token 'date'
jest to, żetime
zużywa go średnik oddzielający godate
. Może to zrobić tylko dlatego, żetime
jest zarezerwowanym słowem bash.źródło
time
powinno pozwalać na polecenie NULL, a średnik ma ograniczać listy, więctime
polecenie IMO nie powinno „zużywać” średnika po nim. Inne wbudowane polecenia (które mogą przyjmować argumenty) nie wykazują tego rodzaju zachowania.time;date
jest w istocie składniowo źle w dowolnej interpretacji. Jednaktime ;
itime ; ;
wtedy też byłoby nielegalne. Można dyskutować, czytime
zachowanie jest błędem, czy tylko nieudokumentowanym ( jest wewnętrznie spójny), ale raport o błędzie na pewno będzie na miejscu. Czy byłbyś skłonny to złożyć?time by itself can time a null command
a potem robi to przez$$ = make_simple_command (x, (COMMAND *)NULL);
. Jeśli chodzi o zgłaszanie błędu, nie jestem pewien 8)time ; date
prace wksh93
imksh
bez błędów, choć wksh
nietime
słów kluczowych.Bash traktuje wbudowany
time
element jako specjalny przypadek podczas analizowania linii poleceń.Jak można przeczytać na stronie podręcznika bash, wpisany wiersz jest najpierw dzielony na listę:
gdzie rurociąg jest:
lub w naszym przypadku po prostu:
tzn. jeśli czas jest obecny, polecenie musi być również obecne.
[Istnieje szczególny przypadek, który pozwala
time
na dodanie nowej linii, ale nie dotyczy to tutaj]W naszym przypadku mamy:
podzielony na dwa rurociągi:
a rurociąg 1 nie jest dobrze uformowany, ponieważ mamy
time
bez polecenia. Stąd błąd.Zauważ, że
time
tutaj również nie działa wiersz poleceń :bash analizuje to zgodnie z oczekiwaniami, w 2 potoki:
a
/usr/bin/time
następnie odmawia uruchomienia bez argumentów. Zauważ, że jest to błąd wynikający z/usr/bin/time
błędu bash.Powodem, dla którego działa tykanie wstecz jest to, że tykanie przestaje
time
być interpretowane jako specjalny element w potoku.tj. z tyknięciem wstecz:
jest analizowany jako dwa potoki:
Pamiętaj, że rurociąg w naszym przypadku to:
a problem początkowo polegał na tym, że nie mieliśmy
time
polecenia, co jest niedozwolone. Ale teraz mamy po prostu polecenie:bez poprzedzającego
time
, ponieważ znaczniki cofania oznaczają, żetime
jest interpretowane jako polecenie, a nie jako poprzedzające słowo.Więc bash następnie uruchamia swoją wbudowaną wersję
time
bez argumentów, co jest akceptowane. Nie wytwarza danych wyjściowych i nie widzimy błędów.Uwaga:
faktycznie prowadzi wynik z następujących
time
wbudowany, czyli działa bez względu natime
wbudowaną produkuje na standardowe wyjście. Ale ponieważtime
sam nie pisze niczego na standardowe wyjście, wydaje się, że działa.Wreszcie zauważono, że to działa:
czego niestety nie potrafię wyjaśnić :)
źródło
;date
dajebash: syntax error near unexpected token ;
, aletime ;date
dajebash: syntax error near unexpected token date
, więc wydaje się, że bash nie traktuje polecenia po wbudowanym czasie jako „; data”. Co ciekawe,time ; ; date
działa.'time'
traci swoje znaczenie jako zarezerwowanego słowa. Ponowne kliknięcie powoduje wykonanie go w podpowłoce, której dane wyjściowe są łączone w komendzie. To nie ma nic wspólnego z dyskusją. W rzeczywistości twój przykład`time\';date
jest sprzeczny z twoim twierdzeniem: powinno to prowadzić do błędu w twoim rozumowaniu, ponieważ/usr/bin/time
wymaga argumentu. Powodem tego nie jest, ponieważ w podpowłoce, w której się wykonuje, jest to słowo zastrzeżonetime
.