Es scheint einige Inkonsistenzen zu geben, die ich in Bezug auf die Bash-Shell nicht verstehen kann.
Wenn ich ausführe:
ls;date;time
Die Ergebnisse der drei Abfragen werden nacheinander angezeigt.
Beim Vertauschen von Datum und Uhrzeit wird jedoch eine Fehlermeldung angezeigt.
Also, wenn ich ausführe:
ls;time;date
Die Fehlermeldung lautet : bash: syntax error near unexpected token 'date'
.
Kann jemand das erklären?
time;date
vsdate;time
. Dies scheint ein Problem mit der Pipelinebash
und dem zuletzt mit dertime
Ausgabe generierten Zeichen zu sein. Getestete Ergebnisse in verschiedenen Terminalemulatoren sind: - [Bash] $ Datum; Zeit # [OK] $ Zeit; Datum # [ NotOK ] Bash: Syntaxfehler in der Nähe des unerwarteten Tokens "Datum" $ Zeit # Nur Fehler erscheint nicht, dass es das ist Ergebnis eines beliebigen Datums. - [Csh] $ Datum; Uhrzeit # [OK] $ Uhrzeit; Datum # [OK] - [Tcsh] $ Datum; Uhrzeit # [OK] $ Uhrzeit; Datum # [OK] - [Ksh] $ Datum; Uhrzeit # [ OK] $ Zeit; Datum # [OK]Antworten:
Der
time
Befehl in Ihrer Pipeline ist nicht die/usr/bin/time
Binärdatei, sondern die integrierte Bashtime
. Vergleicheman time
mithelp time
. Der Fehler, den Sie sehen, ist, dass bash dastime
Argument nicht analysiert . Dies muss entweder vorhanden sein oder eine neue Zeile sein. Es ist eine neue Zeile in Ihrem ersten Beispiel, fehlt aber im zweiten.Auf der anderen Seite, wenn Sie rennen würden
oder
Wenn die Anführungszeichen
'time'
den Status als reserviertes Wort widerrufen, hat bash keine Probleme, die Zeile zu analysieren. Es analysiert nun drei Befehle in einer Liste, die nacheinander ausgeführt werden, und/usr/bin/time
meldet in beiden Fällen einen Verwendungsfehler.Nachtrag
Es wurde beobachtet, dass dies zwar
time ; date
einen Fehler ergibt, diestime ; ; date
jedoch nicht der Fall ist. Die wahrscheinliche Erklärung ist, dasstime ;
von Bash als äquivalent zu interpretiert wirdtime <newline>
. Der Ausdrucktime ; ; date
wird dann als Liste vontime ;
und analysiertdate
.Dies steht im Einklang mit der Beobachtung, dass
time ;
undtime ; ;
auch legal sind, wobei die zweite als Singleton-Liste analysiert wird, dietime ;
das optionale Semikolon enthält, das nach Listen zulässig ist.Eine andere Möglichkeit zu erklären, warum
time ; date
der Fehler auftritt,bash: syntax error near unexpected token 'date'
besteht darin,time
das Semikolon zu verbrauchen, von dem er getrennt istdate
. Das kann es nur, weiltime
es ein Bash-reserviertes Wort ist.quelle
time
soll einen NULL-Befehl zulassen, und das Semikolon soll Listen abgrenzen, sodass dertime
Befehl IMO das Semikolon danach nicht "verbrauchen" sollte. Andere eingebaute Befehle (die Argumente annehmen können) zeigen dieses Verhalten nicht.time;date
ist in der Tat syntaktisch falsch in jeder Interpretation. Allerdingstime ;
undtime ; ;
wäre dann auch illegal. Es kann diskutiert werden, obtime
das Verhalten ein Fehler ist oder nur undokumentiert (es ist intern konsistent), aber ein Fehlerbericht wäre definitiv vorhanden. Wären Sie bereit, es einzureichen?time by itself can time a null command
und dann tut es das durch$$ = make_simple_command (x, (COMMAND *)NULL);
. Was das Einreichen eines Fehlerstime ; date
funktioniert inksh93
undmksh
ohne Fehler, obwohlksh
es eintime
Schlüsselwort gibt.Bash behandelt das Integrierte
time
als Sonderfall beim Parsen von Befehlszeilen.Wie in der Bash-Manpage zu lesen ist, wird die eingegebene Zeile zunächst in eine Liste aufgeteilt:
wo sich eine Pipeline befindet:
oder in unserem Fall einfach:
dh wenn Zeit vorhanden ist, muss auch ein Befehl vorhanden sein.
[Es gibt einen Sonderfall,
time
in dem eine neue Zeile folgen kann, der hier jedoch nicht gilt.]In unserem Fall haben wir also:
in zwei Pipelines aufgeteilt werden:
und Pipeline 1 ist nicht gut ausgebildet, da wir
time
ohne Befehl haben. Daher der Fehler.Beachten Sie, dass die Befehlszeile auch
time
hier nicht funktioniert:bash analysiert dies wie erwartet in 2 Pipelines:
und
/usr/bin/time
weigert sich dann, ohne Argument zu laufen. Beachten Sie, dass dies ein Fehler ist,/usr/bin/time
nicht ein Fehler von bash.Der Grund dafür, dass Back-Tick funktioniert, ist, dass das Back-Tick nicht
time
mehr als spezielles Element in der Pipeline interpretiert wird.dh mit dem Back-Tick:
Es wird als zwei Pipelines analysiert:
Denken Sie daran, dass eine Pipeline in unserem Fall wie folgt lautet:
und das problem war anfangs, dass wir
time
ohne befehl hatten, was nicht erlaubt ist. Aber jetzt haben wir einfach den Befehl:ohne das Vorhergehende
time
, da die Back-Ticks bedeuten, dass diestime
als Befehl und nicht als Vorgängerwort interpretiert wird.Bash führt dann sein eingebautes System
time
ohne Argumente aus, was akzeptiert wird. Es wird keine Ausgabe erzeugt, und wir sehen keinen Fehler.Beachten Sie, dass:
führt tatsächlich das Ergebnis des
time
eingebauten Systems aus, dh es wird ausgeführt, was auch immer dastime
eingebaute auf stdout erzeugt. Aber datime
alleine nichts zu stdout schreibt, scheint es zu funktionieren.Schließlich wurde festgestellt, dass dies funktioniert:
was ich leider nicht erklären kann :)
quelle
;date
gibtbash: syntax error near unexpected token ;
, abertime ;date
gibtbash: syntax error near unexpected token date
, so dass es scheint, dass bash den Befehl nach der eingebauten Zeit nicht als "; Datum" behandelt. Interessanterweisetime ; ; date
funktioniert.'time'
verliert es seine Bedeutung als reserviertes Wort. Wenn Sie es zurückticken , wird es in einer Subshell ausgeführt, deren Ausgabe in den Befehl eingefügt wird. Dies hat nichts mit der Diskussion zu tun. In der Tat`time\';date
beweist Ihr Beispiel das Gegenteil Ihrer Behauptung: Dies sollte durch Ihre Argumentation einen Fehler ergeben, da/usr/bin/time
ein Argument erforderlich ist. Der Grund dafür ist, dass es sich in der Subshell, in der es ausgeführt wird, wieder um das reservierte Wort handelttime
.