




Это потому, что в синтаксисе оболочки ; и & не могут быть частью «слова» (если они не заключены в кавычки или экранированы), а { и } могут. Таким образом, {sleep 1 будет проанализировано как одно слово, и вы получите ошибку «{sleep: команда не найдена», и echo 123} напечатает 123}, а echo 123; или echo 123& просто напечатает «123» и обработает ; или & как разделитель команды, а не часть аргумента команды.
В конкретном случае 123;}& он рассматривает 123 как слово (которое будет аргументом для echo), но ; не может быть частью этого слова, поэтому он рассматривается как начало нового токена, даже если нет пространство для его разграничения. Затем он проверяет ;}, и это не имеет смысла (например, ;; или ;&), поэтому он снова рассматривает } как начало нового токена — на этот раз «слово» (которое в конечном итоге будет рассматриваться как ключевое слово , например {, if, then и т. д.). Затем он видит }&, а & не может быть частью этого слова, поэтому он снова воспринимает его как новый токен, даже если места нет.
Если вы экранируете или цитируете ; и/или &, они будут рассматриваться как часть того же слова, что и }, если только вы не добавите пробелы в качестве разделителей. Например:
$ { sleep 1; echo 123';'}&
> }
[1] 45306
123;}
$
[1]+ Done echo 123';'}
Что там произошло? Ну, ; был заключен в кавычки, поэтому он и } рассматривались как часть аргумента echo, а это означает, что bash все еще ждал ключевого слова }, чтобы закрыть группу команд, поэтому он запросил это с помощью ">". Я дал ему желаемый }, поэтому он заснул на секунду, а затем повторил «123;}» (в фоновом режиме, поэтому он напечатал идентификатор процесса bg и сообщения о состоянии).
Подводя итог, можно сказать, что иногда можно обойтись без пробелов в качестве разделителей между синтаксическими элементами в bash, но правила сложны и, вероятно, не заслуживают полного понимания. В случае сомнений используйте пробелы в качестве явных разделителей.
после прочтения руководства по bash ; и & являются метасимволами, они разделяют слова, а { и } являются ключевыми словами
@yuanjianpeng: Я думаю, что «они разделяют утверждения» было бы точнее. Конечно, разделитель операторов также является разделителем слов, поскольку слово не может выходить за границы операторов.
Правила перечислены здесь pubs.opengroup.org/onlinepubs/9699919799/utilities/… в разделе «Зарезервированные слова» и не так уж сложны.