Почему `sort <(ls -l)` работает, но `sort <(ls -l) `fail?

Сегодня я узнаю что-то о fifo с этой статьей: Введение в именованные каналы , в котором упоминается cat <(ls -l)

Я сделал несколько экспериментов, используя sort < (ls -l), который выдает сообщение об ошибке:

-bash: syntax error near unexpected token `('`

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

Но почему эта дополнительная команда приведет к этой ошибке? Почему символ перенаправления должен быть близок к (?

33 голоса | спросил Zen 11 thEurope/Moscowp30Europe/Moscow09bEurope/MoscowFri, 11 Sep 2015 14:03:05 +0300 2015, 14:03:05

1 ответ


22

Потому что так оно и должно быть.

<(...) в bash - это синтаксис для замещения процесса. Он копируется из одного и того же оператора в ksh.

<, (, ---- +: = 5 =: + ----, ), |, & - специальные лексические токены в ;, которые используются для формирования специальных операторов в разных комбинациях. bash, <, <(, << ... каждая из них играет свою роль. <& предназначен для перенаправления. <, <file будет перенаправлять ввод с файл. < file будет перенаправлять ввод из файла с именем <'(file)', но (file) - это другой оператор, который не является оператором перенаправления.

<(file) будет < (file) по <. В этом контексте в (file), bash не действует. (file) может быть действительным как один токен в некоторых контекстах, таких как:

(...)

Но не в

(sub shell)
func () {
  ...
}
var=(foo bar)

В оболочке sort < (cmd) это другое. В fish, fish используется для замены команд (эквивалент (...) в $(...)) , И bash предназначен для перенаправления ввода, как в Bourne-подобных оболочках.

Итак, в <:

fish

будет таким же, как:

sort <(echo file)

То есть:

sort < (echo file)

Но это нечто совершенно отличное от замены sort < file .

В оболочке bash другая оболочка POSIX, yash не для подстановки процесса , а для перенаправления процессов

Там,

<(...)

Сокращение для:

sort <(ls -l)

- оператор перенаправления. Это более или менее эквивалентно:

sort 0<(ls -l)

В ls -l | sort , bash расширяется до пути к каналу, так что это больше похоже на:

<(ls -l)

В ls -l | sort /dev/fd/0 , zsh ((...) будет расширяться до (*.txt|*.png) и txt) и в качестве классификатора glob (png, например, расширяет файлы каталога).

В *(/), в:

zsh

Этот sort < (ls -l) будет рассматриваться как квалификатор glob. Кластер (ls -l) glob должен соответствовать количеству ссылок и ожидает номер после l (как в l будут перечислены файлы с 2-мя ссылками), поэтому вы получаете ---- +: = 59 =: + ----.

ls -ld ./*(l2) дал бы код zsh: number expected вместо sort < (w) соответствует файлам с пустым именем, которые можно записать.

zsh: no matches found: (w) будет сортировать содержимое (w) и /или sort < (w|cat) в текущем каталоге ...

ответил Stéphane Chazelas 11 thEurope/Moscowp30Europe/Moscow09bEurope/MoscowFri, 11 Sep 2015 15:28:44 +0300 2015, 15:28:44

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

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132