Bash: почему нельзя поставить перенаправление перед сгруппированными командами с помощью фигурных скобок - PullRequest
0 голосов
/ 05 января 2020

Не удалось выполнить следующую команду оболочки:

$ >/dev/null { : ; }
-bash: syntax error near unexpected token `}'

, но если поставить перенаправление до выполнения простой команды:

$ >/dev/null :

Это не упоминается в bash руководстве.

1 Ответ

3 голосов
/ 05 января 2020

почему нельзя поставить перенаправление перед сгруппированными командами с помощью фигурных скобок

Поскольку грамматика языка запрещает это.

Из инструкция оболочки posix В 2.4 Reserved words можно прочесть следующее выделение мин:

Следующие слова должны быть распознаны как зарезервированные слова:

! do esa c in
{done fi затем
} elif для до
, в противном случае, если while

Это распознавание должно происходить только тогда, когда ни один из символов не указан в кавычках и когда слово используется как:

  • Первое слово команды

  • Первое слово после одного из зарезервированных слов, отличных от case, for или in

  • Третье слово в команде case (в этом случае действует только in)

  • Третье слово в Команда a for (только в этом случае и действительны в этом случае)

Для {, чтобы ввести группировку команд, это должно быть первое слово в команде. То же самое относится, например, к </dev/null if false; them echo 1; fi или </dev/null while true; do echo 1; done. Зарезервированное слово должно быть первым словом в команде.

Как мне это сделать

Вы ставите его после фигурных скобок или команды. Он будет «применять» перенаправление для всех команд «внутри» группировки.

{ echo 1; } >/dev/null
while echo this will go to file1; do echo this too; break; done >/tmp/file1.txt
if read a; then read b; echo yes; else echo no; fi </tmp/file1 >/tmp/file2

следующим образом: $ (Q) {xxx; }

Это невозможно, так как перенаправление анализируется до расширения подстановки команды $(...). Вы не можете написать это так. Вы можете использовать eval для переоценки своего выражения, но eval - это одна буква от зла ​​. Правильный способ поиска - это, скорее всего, перенаправить стандартный вывод или пользовательский дескриптор файла в конечный файл, используя exec, например exec 1>/dev/null или exec {FD}>/dev/null; { cmd; } >${FD}.

.
...