Почему последовательность имеет значение при выполнении этих команд bash?

Кажется, есть некоторая несогласованность, которую я не могу понять в отношении оболочки bash.

Если я выполню:

ls;date;time

результаты трех запросов будут показаны последовательно.

Однако, при смене даты и времени, появляется сообщение об ошибке.

Поэтому, если я выполню:

ls;time;date

сообщение об ошибке гласит: bash: syntax error near unexpected token 'date'.

Может кто-нибудь объяснить это?

10
задан 6 March 2013 в 10:35

2 ответа

Bash рассматривает встроенное time как особый случай, при парсинге командных строк.

Как может быть считан в странице справочника удара, строка, как введено сначала разделяется на список:

pipeline ; pipeline

где конвейер:

[time [-p]] [ ! ] command [ [|⎪|&] command2 ... ]

или в нашем случае, просто:

time command

т.е. если время присутствует, то управляйте, должен также присутствовать.

[Существует особый случай, который позволяет time чтобы сопровождаться новой строкой, но это не применяется здесь]

Так, в нашем случае мы имеем:

time;date

быть разделенным на два конвейера:

1. time
2. date

и конвейер 1 не хорошо формируется, так как мы имеем time без команды. Следовательно ошибка.

Обратите внимание что командная строка time не работает здесь также:

$ /usr/bin/time;date
Usage: /usr/bin/time [-apvV] [-f format] [-o file] [--append] [--verbose]

колотите анализирует это как ожидалось, в 2 конвейера:

1. /usr/bin/time
2. date

и /usr/bin/time затем отказывается работать без аргумента. Обратите внимание, что это - ошибка от /usr/bin/time не ошибка от удара.

Причина, что обратная галочка работает, состоит в том, что обратная галочка останавливается time будучи интерпретируемым как специальный элемент в конвейере.

т.е. с обратной галочкой:

`time`;date

это анализируется как два конвейера:

1. `time`
2. date

Помните, что конвейер, в нашем случае:

[time] command

и проблема первоначально состояла в том, что мы имели time без команды, которая не позволяется. Но теперь у нас просто есть команда:

`time`

без предыдущего time, так как обратные галочки означают это time интерпретируется как команда, не как предыдущее слово.

Таким образом, удар затем выполняет свое встроенное time без args, который принят. Это не производит вывода, и мы не видим ошибки.

Обратите внимание что:

`time`

на самом деле выполняет результат time встроенный, т.е. это работает что time встроенные продукты на stdout. Но с тех пор time самостоятельно ничего не пишет в stdout, это, кажется, работает.

Наконец, было отмечено, что это работает:

time ; ; date

который я не могу объяснить, печально :)

2
ответ дан 6 March 2013 в 10:35

Команда time в вашем конвейере является не двоичным /usr/bin/time, а встроенным в bash time. Сравните man time с help time. Ошибка, которую вы видите, заключается в том, что bash не удалось разобрать аргумент time. Это должно присутствовать или быть новой строкой. Это символ новой строки в вашем первом примере, но отсутствует во втором.

С другой стороны, если вы запустили

ls;date;'time'

или

ls;'time';date

, где кавычки вокруг '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.

0
ответ дан 6 March 2013 в 10:35

Другие вопросы по тегам:

Похожие вопросы: