Сегодня я узнаю кое-что о fifo в этой статье: Введение в именованные каналы , в которой упоминается cat <(ls -l)
.
Я сделал несколько экспериментов с использованием sort < (ls -l)
, которое выскакивает ошибка:
-bash: syntax error near unexpected token `('`
Затем я обнаружил, что неправильно ввел лишний пробел в команде.
Но почему эта дополнительная команда приведет к этому провалу? Почему символ перенаправления должен быть близко к (
?
Ответы:
Потому что это не
<
, это<()
совершенно другое. Это называется заменой процесса , это особенность определенных оболочек, которая позволяет использовать выходные данные одного процесса в качестве входных данных для другого.Операторы
>
и<
перенаправляют вывод и ввод из файлов .<()
Оператор имеет дело с командами (процессы), а не файлы. Когда ты бежишьВы пытаетесь выполнить команду
ls
в подоболочке (это означает, что в скобках), а затем передать эту подоболочку в качестве входного файлаsort
. Это, однако, неприемлемый синтаксис, и вы получите ошибку, которую вы видели.источник
then sort is attempting to read the subshell as its input file
→ это, очевидно, неправильно, поскольку Bash даже не будет анализировать синтаксис. Ни на самом делеls
ниsort
беги.< (ls)
здесь недействительный токен(ls)
будет работатьls
в подоболочке.Потому что так и должно быть.
<(...)
вbash
это синтаксис для замены процесса. Он скопирован с того же оператора вksh
.<
,(
,)
,|
,&
,;
Специальные лексические маркеры вbash
которые используются для формирования специальных операторов в различных комбинациях.<
,<(
,<<
,<&
... каждый имеет свою роль.<
для перенаправления.<file
,< file
перенаправил бы ввод из файла.<'(file)'
будет перенаправлять ввод из файла с именем(file)
, но<(file)
это другой оператор, который не является оператором перенаправления.< (file)
будет<
затем(file)
. В этом контексте, вbash
,(file)
не является действительным.(...)
может быть действительным как один токен в некоторых контекстах, таких как:Но не в
В
fish
оболочке все по-другому. Вfish
,(...)
для подстановки команд (эквивалент$(...)
вbash
). И<
для перенаправления ввода, как в Bourne-подобных оболочках.Итак, в
fish
:будет так же, как:
То есть:
Но это нечто совершенно отличное от
bash
процесса замещения в России.В
yash
оболочке, другая оболочка POSIX,<(...)
предназначена не для замены процесса, а для перенаправления процессаТам,
Короче для:
является оператором перенаправления. Это более или менее эквивалентно:
Находясь внутри
bash
,<(ls -l)
он расширяется до пути трубы, так что это больше похоже на:В
zsh
,(...)
перегружен как оператор глобинга ((*.txt|*.png)
будет расширяться доtxt
иpng
файлы) и как спецификатор глобуса (*(/)
например, расширяется до файлов каталога).В
zsh
, в:Это
(ls -l)
будет рассматриваться как глобус квалификатор.l
Глоб классификатор должен соответствовать по количеству ссылок и ожидает , что число послеl
(какls -ld ./*(l2)
бы список файлов с 2 ссылки), так вот почему вы получитеzsh: number expected
ошибку там.sort < (w)
дал быzsh: no matches found: (w)
ошибку вместо того, чтобы, как(w)
спички файлы с пустым именем, которые записываемые.sort < (w|cat)
отсортировал бы содержимое файловw
и / илиcat
в текущем каталоге ...источник
sort < $(ls -l)
выдает такую ошибку:bash: $(ls -l): ambiguous redirect
$(ls -l)
расширяется до более чем одного слова. Используйте кавычки, чтобы предотвратить split + glob (sort < "$(echo file)"
). Обратите внимание, что поведение илиbash
отличается от POSIX sh в этом bash делает это split + glob там, когда он неинтерактивен (не когда вызывается так, какsh
если бы).ls -l | sort /dev/fd/0
я могу сказать, что выходные данныеls -l
хранятся в,/dev/fd/0
аsort
команда читает их, чтобы получить желаемый результат. Я используюtail -f --retry /dev/fd/0
для мониторинга этого файла, но я не получаю никакого вывода. Зачем? как я могу прочитать этот файл?(foo | psub)
для достижения замены процесса ввода; пока нет замены (га) для замены процесса вывода.