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

10

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

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

ls;date;time

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

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

Итак, если я выполняю:

ls;time;date

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

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

    
задан rohitvijaysharma 06.03.2013 в 05:50
источник

2 ответа

10

Команда 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.

    
ответ дан zwets 06.03.2013 в 06:47
2

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

Как можно прочитать в man-странице bash, строка, напечатанная, сначала разбивается на список:

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]

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

1. /usr/bin/time
2. date

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

Причина, по которой работает back-tick, заключается в том, что back-tick останавливает time , который интерпретируется как специальный элемент в конвейере.

то есть. с обратным тиком:

'time';date

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

1. 'time'
2. date

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

[time] command

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

'time'

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

Итак, bash запускает свой встроенный time без аргументов, который принимается. Он не производит выход, и мы не видим ошибки.

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

'time'

фактически запускает результат встроенного time , т. е. он запускает все, что встроено в time на stdout. Но так как time сам по себе не пишет ничего в stdout, он работает.

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

time ; ; date

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

    
ответ дан cdmackay 07.03.2013 в 19:39