Hoy estoy aprendiendo algo sobre fifo con este artículo: Introducción a las tuberías con nombre , que menciona cat <(ls -l)
.
Hice algunos experimentos usando sort < (ls -l)
, lo que muestra un error:
-bash: syntax error near unexpected token `('`
Luego descubrí que había agregado un espacio extra en el comando.
Pero, ¿por qué este comando adicional conducirá a este fracaso? ¿Por qué el símbolo de redireccionamiento debe estar cerca del (
?
Respuestas:
Porque eso no es un
<
,<()
es algo completamente diferente. Esto se llama sustitución de proceso , es una característica de ciertos shells que le permite usar la salida de un proceso como entrada para otro.Los operadores
>
y<
redirigen la salida y la entrada de los archivos . El<()
operador maneja comandos (procesos), no archivos. Cuando corresEstá intentando ejecutar el comando
ls
en una subshell (eso es lo que significan los paréntesis), luego pasar esa subshell como un archivo de entradasort
. Sin embargo, esta sintaxis no es aceptada y obtiene el error que vio.fuente
then sort is attempting to read the subshell as its input file
→ esto obviamente es incorrecto, ya que Bash ni siquiera analizará la sintaxis. Nils
tampocosort
se ejecuta realmente.< (ls)
No es un token válido aquí.(ls)
se ejecutaríals
en una subshell.Porque así es como debe ser.
<(...)
inbash
es la sintaxis para la sustitución de procesos. Se copia del mismo operador enksh
.<
,(
,)
,|
,&
,;
Son tokens léxicos especiales enbash
que se utilizan para formar operadores especiales en diferentes combinaciones.<
,<(
,<<
,<&
... cada uno tiene su papel.<
es por redireccionamiento.<file
,< file
redirigiría la entrada de un archivo.<'(file)'
redirigiría la entrada de un archivo llamado(file)
, pero<(file)
es un operador diferente que no es un operador de redirección.< (file)
sería<
seguido por(file)
. En ese contexto, enbash
,(file)
no es válido.(...)
puede ser válido como un token único en algunos contextos como:Pero no en
En la
fish
cáscara, es diferente. Infish
,(...)
es para la sustitución de comandos (el equivalente de$(...)
inbash
). Y<
es para la redirección de entrada como en shells tipo Bourne.Entonces en
fish
:sería lo mismo que:
Es decir:
Pero eso es algo completamente diferente de
bash
la sustitución del proceso.En el
yash
shell, otro shell POSIX,<(...)
no es para la sustitución de procesos sino para la redirección de procesos.Ahí,
Corto para:
es un operador de redireccionamiento. Es más o menos equivalente a:
Mientras está adentro
bash
,<(ls -l)
se expande a la ruta de una tubería, por lo que es más como:En
zsh
,(...)
se sobrecarga como operador global ((*.txt|*.png)
se expandiría atxt
ypng
archivos) y como calificador global (*(/)
por ejemplo, se expande a archivos de directorio).En
zsh
, en:Eso se
(ls -l)
trataría como un calificador global. Ell
calificador global es coincidir en el número de enlaces y espera un número despuésl
(comols -ld ./*(l2)
se enumeraría en los archivos con 2 enlaces), así que es por eso que obtiene unzsh: number expected
error allí.sort < (w)
habría dado unzsh: no matches found: (w)
error en su lugar, ya que(w)
coincide con los archivos con nombre vacío que se pueden escribir.sort < (w|cat)
habría ordenado el contenido de los archivosw
y / ocat
en el directorio actual ...fuente
sort < $(ls -l)
da este error:bash: $(ls -l): ambiguous redirect
$(ls -l)
expande a más de una palabra. Use comillas para evitar split + glob (sort < "$(echo file)"
). Tenga en cuenta que el comportamiento obash
difiere del de POSIX sh en ese bash hace que la división + glob allí también cuando no sea interactiva (no cuando se llama comosh
si fuera).ls -l | sort /dev/fd/0
, puedo decir que la salida dels -l
se almacena en/dev/fd/0
y elsort
comando lo lee para dar la salida deseada. Estoy usandotail -f --retry /dev/fd/0
para monitorear ese archivo pero no obtengo ningún resultado. ¿por qué? ¿Cómo puedo leer ese archivo?(foo | psub)
para lograr la sustitución del proceso de entrada; todavía no hay sustituto (ha) para la sustitución del proceso de salida.