Hoje estou aprendendo algo sobre o fifo com este artigo: Introdução aos tubos nomeados , que menciona cat <(ls -l)
.
Fiz algumas experiências usando sort < (ls -l)
, o que mostra um erro:
-bash: syntax error near unexpected token `('`
Então, descobri que não havia espaço suficiente no comando.
Mas, por que esse comando extra levará a essa falha? Por que o símbolo de redirecionamento deve estar próximo ao (
?
Respostas:
Porque isso não é um
<
, é um<()
que é completamente diferente. Isso é chamado de substituição de processo , é um recurso de certas shells que permite usar a saída de um processo como entrada para outro.Os operadores
>
e<
redirecionam a saída e a entrada dos arquivos . O<()
operador lida com comandos (processos), não com arquivos. Quando você correVocê está tentando executar o comando
ls
em um subshell (é o que os parênteses significam) e depois passar esse subshell como um arquivo de entradasort
. No entanto, essa sintaxe não é aceita e você recebe o erro que viu.fonte
then sort is attempting to read the subshell as its input file
→ isso está obviamente errado, pois o Bash nem sequer analisa a sintaxe. Nemls
nemsort
é realmente executado.< (ls)
não é um token válido aqui.(ls)
seria executadols
em um subshell.Porque é assim que deve ser.
<(...)
inbash
é a sintaxe da substituição do processo. É copiado do mesmo operador emksh
.<
,(
,)
,|
,&
,;
São símbolos lexicais especiais embash
que são usados para formar os operadores especiais em diferentes combinações.<
,<(
,<<
,<&
... cada um tem o seu papel.<
é para redirecionamento.<file
,< file
redirecionaria a entrada de um arquivo.<'(file)'
redirecionaria a entrada de um arquivo chamado(file)
, mas<(file)
é um operador diferente que não é um operador de redirecionamento.< (file)
seria<
seguido por(file)
. Nesse contexto, embash
,(file)
não é válido.(...)
pode ser válido como um único token em alguns contextos como:Mas não em
No
fish
shell, é diferente. Infish
,(...)
é para substituição de comando (o equivalente a$(...)
inbash
). E<
é para redirecionamento de entrada como em shells tipo Bourne.Então em
fish
:seria o mesmo que:
Isso é:
Mas isso é algo completamente diferente da
bash
substituição de processos.No
yash
shell, outro shell POSIX,<(...)
não é para substituição de processo, mas para redirecionamento de processoLá,
Abreviatura de:
é um operador de redirecionamento. É mais ou menos equivalente a:
Enquanto estiver no
bash
, o<(ls -l)
é expandido para o caminho de um tubo, por isso é mais como:In
zsh
,(...)
é sobrecarregado como um operador globbing ((*.txt|*.png)
seria expandido paratxt
epng
arquivos) e como qualificador global (*(/)
por exemplo, se expande para arquivos de diretório).Em
zsh
, em:Isso
(ls -l)
seria tratado como um qualificador global. Ol
qualificador glob deve corresponder ao número de links e espera um número depoisl
(como emls -ld ./*(l2)
listaria os arquivos com 2 links), é por isso que você recebe umzsh: number expected
erro lá.sort < (w)
emzsh: no matches found: (w)
vez disso , teria dado um erro, pois(w)
corresponde aos arquivos com um nome vazio que pode ser gravado.sort < (w|cat)
teria classificado o conteúdo dos arquivosw
e / oucat
no diretório atual ...fonte
sort < $(ls -l)
dá esse erro:bash: $(ls -l): ambiguous redirect
$(ls -l)
expande para mais de uma palavra. Use aspas para evitar divisão + glob (sort < "$(echo file)"
). Observe que o comportamento oubash
difere do POSIX sh nesse bash faz com que o divisão + glob também seja inativo (não quando chamado como sesh
fosse).ls -l | sort /dev/fd/0
posso dizer que a saída dels -l
é armazenada/dev/fd/0
e osort
comando lê para fornecer a saída desejada. Estou usandotail -f --retry /dev/fd/0
para monitorar esse arquivo, mas não estou obtendo nenhuma saída. porque? como posso ler esse arquivo?(foo | psub)
para obter a substituição do processo de entrada; ainda não há substituto (ha) para substituição do processo de saída.