Кажется, есть некоторая несогласованность, которую я не могу понять в отношении оболочки bash.
Если я выполню:
ls;date;time
Результаты трех запросов показаны в последовательности.
Однако при смене даты и времени всплывает сообщение об ошибке.
Итак, если я выполню:
ls;time;date
сообщение об ошибке говорит: bash: syntax error near unexpected token 'date'
.
Может кто-нибудь объяснить это?
time;date
противdate;time
. Это, похоже, проблема с конвейеромbash
и последним символом, сгенерированным сtime
выходом. Результаты тестирования в различных эмуляторах терминала: - [Bash] $ date; time # [OK] $ time; date # [ NotOK ] bash: синтаксическая ошибка рядом с неожиданным токеном `date '$ time # только ошибка не появляется, что это результат любой даты. - [Csh] $ date; время # [OK] $ время; date # [OK] - [Tcsh] $ date; время # [OK] $ время; date # [OK] - [Ksh] $ date; время # [ OK] $ time; дата # [OK]Ответы:
Команда
time
в вашем конвейере не/usr/bin/time
двоичная, аtime
встроенная в bash . Сравнитеman time
сhelp time
. Ошибка, которую вы видите, это то, что bash не может разобратьtime
аргумент. Это должно или присутствовать или быть новой строкой. Это новая строка в вашем первом примере, но отсутствует во втором.С другой стороны, если вы должны были бежать
или
где кавычки
'time'
аннулируют его статус зарезервированного слова, тогда bash без проблем разбирает строку. Теперь он анализирует три команды в списке, которые он будет выполнять последовательно, и/usr/bin/time
сообщит об ошибке использования в любом случае.добавление
Было отмечено, что, хотя и
time ; date
дает ошибку,time ; ; date
нет. Вероятное объяснение состоит в том, чтоtime ;
bash интерпретируется как эквивалентноеtime <newline>
. Затем выражениеtime ; ; date
анализируется как списокtime ;
иdate
.Это согласуется с наблюдением , что
time ;
иtime ; ;
являются законными , а также, второе существо обрабатываются как список одноплодного , содержащиеtime ;
затем необязательной точка с запятой после списка.Итак, еще один способ объяснить, почему
time ; date
выдает ошибку,bash: syntax error near unexpected token 'date'
состоит в том, что онаtime
использует точку с запятой, отделяющую ее отdate
. Это может быть сделано только потому, чтоtime
это зарезервированное слово bash.источник
time
предполагается, что команда NULL допускается, а точка с запятой должна разделять списки, поэтому IMOtime
команда не должна «использовать» точку с запятой после нее. Другие встроенные команды (которые могут принимать аргументы) не демонстрируют такого рода поведение.time;date
это действительно синтаксически неправильно в любой интерпретации. Однакоtime ;
иtime ; ;
тогда тоже будет незаконным. Можно спорить лиtime
поведение «S является ошибкой или просто без документов (она является внутренне непротиворечивой), но сообщение об ошибке, несомненно , будет на месте. Вы хотели бы подать это?time by itself can time a null command
и затем он делает это$$ = make_simple_command (x, (COMMAND *)NULL);
. Что касается регистрации ошибки, я не уверен, 8)time ; date
работ вksh93
иmksh
без каких - либо ошибок, даже если вksh
естьtime
ключевое слово.Bash рассматривает встроенное
time
как особый случай при разборе командных строк.Как можно прочитать на man-странице bash, набранная строка сначала разбивается на список:
где трубопровод:
или в нашем случае просто:
т.е. если время присутствует, то команда должна также присутствовать.
[Существует особый случай, который позволяет
time
следовать за новой строкой, но это не относится здесь]Итак, в нашем случае мы имеем:
разделяется на два трубопровода:
и конвейер 1 не очень хорошо сформирован, так как у нас
time
без команды. Отсюда и ошибка.Обратите внимание, что командная строка
time
здесь тоже не работает:bash разбирает это, как и ожидалось, на 2 конвейера:
а
/usr/bin/time
затем отказывается бежать без аргументов. Обратите внимание, что это ошибка, а/usr/bin/time
не ошибка bash.Причина, по которой обратная галочка работает, заключается в том, что обратная галочка перестает
time
интерпретироваться как специальный элемент в конвейере.то есть с обратной галочкой:
он разбирается как два конвейера:
Помните, что конвейер в нашем случае это:
и проблема изначально заключалась в том, что у нас не
time
было команды, что запрещено. Но теперь у нас просто есть команда:без предшествующего
time
, поскольку обратные галочки означают, чтоtime
интерпретируется как команда, а не как предыдущее слово.Таким образом, bash запускает свою встроенную систему
time
без аргументов, что принимается. Он не производит вывод, и мы не видим ошибки.Обратите внимание, что:
фактически запускает результат из
time
встроенной, то есть он работает независимо отtime
встроенного производит на стандартный вывод. Но поскольку самtime
по себе ничего не пишет в stdout, похоже, он работает.Наконец, было отмечено, что это работает:
что я не могу объяснить, к сожалению :)
источник
;date
даетbash: syntax error near unexpected token ;
, ноtime ;date
даетbash: syntax error near unexpected token date
, поэтому кажется, что bash не обрабатывает команду после встроенного времени как "; date". Интересно,time ; ; date
работает.'time'
она теряет свое значение как зарезервированное слово. Откат назад заставляет его выполняться в подоболочке, чей вывод включается в команду. Это не имеет ничего общего с обсуждением. Фактически, ваш пример`time\';date
доказывает противоположность вашего утверждения: это должно привести к ошибке по вашим рассуждениям, потому что/usr/bin/time
требует аргумента. Причина этого заключается в том, что в подоболочке, в которой он выполняется, этоtime
снова зарезервированное слово .