En bash
, puedo usar la sustitución de procesos y tratar la salida de un proceso como si fuera un archivo guardado en el disco:
$ echo <(ls)
/dev/fd/63
$ ls -lAhF <(ls)
lr-x------ 1 root root 64 Sep 17 12:55 /dev/fd/63 -> pipe:[1652825]
desafortunadamente, la sustitución de procesos no es compatible con dash
.
¿Cuál sería la mejor manera de emular Process Substitution
en el tablero?
No quiero guardar el resultado como un archivo temporal en algún lugar ( /tmp/
) y luego tengo que eliminarlo. ¿Hay una forma alternativa?
process-substitution
dash
Martin Vegter
fuente
fuente
bash
en su dispositivo?/dev/fd
y el uso enxz -cd <file>
lugar decat <file> | xz -d
)xz -cd "$1" | { xz -cd "$2" | { diff /dev/fd/3 /dev/fd/4; } 3<&0; } 4<&0
.Respuestas:
La pregunta en el aviso de recompensa actual:
Parece tener una respuesta aquí .
Como se muestra en la respuesta de Gilles , la idea general es enviar la salida de los comandos "productor" a los nuevos archivos 1 del dispositivo en diferentes etapas de una tubería, dejándolos disponibles para los comandos "consumidores", que posiblemente puedan tomar nombres de archivos como argumentos ( asumiendo que su sistema le da acceso a descriptores de archivo como
/dev/fd/X
).La forma más sencilla de lograr lo que está buscando es probablemente:
(Utilizando
file1.xz
en lugar de"$1"
legibilidad y enxz -cd
lugar decat ... | xz -d
porque un solo comando es suficiente).La salida del primer comando "productor"
xz -cd file1.xz
, se canaliza a un comando compuesto ({...}
); pero, en lugar de consumirse inmediatamente como la entrada estándar del siguiente comando, se duplica al descriptor de archivo3
y, por lo tanto, se hace accesible a todo lo que se encuentra dentro del comando compuesto como/dev/fd/3
. La salida del segundo comando "productor"xz -cd file2.xz
, que no consume ni su entrada estándar ni nada del descriptor de archivo3
, se canaliza al comando "consumidor"diff
, que lee de su entrada estándar y de/dev/fd/3
.La duplicación de la tubería y del descriptor de archivo se puede agregar para proporcionar archivos de dispositivo para tantos comandos de "productor" como sea necesario, por ejemplo:
Si bien puede ser irrelevante en el contexto de su pregunta específica, vale la pena señalar que:
cmd1 <(cmd2) <(cmd3)
,cmd2 | { cmd3 | { cmd1 /dev/fd/3 /dev/fd/4; } 4<&0; } 3<&0
y( cmd2 | ( cmd3 | ( cmd1 /dev/fd/3 /dev/fd/4 ) 4<&0 ) 3<&0 )
tienen diferentes efectos potenciales en el entorno de ejecución inicial.Al contrario de lo que sucede en
cmd1 <(cmd2) <(cmd3)
,cmd3
ycmd1
encmd2 | { cmd3 | { cmd1 /dev/fd/3 /dev/fd/4; } 4<&0; } 3<&0
no podrá leer ninguna entrada del usuario. Eso requerirá más descriptores de archivo. Por ejemplo, para que coincidanecesitarás algo como
1 Puede encontrar más información sobre ellos en U&L, por ejemplo, en Understanding / dev y sus subdirecciones y archivos .
fuente
Puede reproducir lo que hace el caparazón debajo del capó haciendo la plomería manualmente. Si su sistema tiene entradas, puede usar la combinación aleatoria de descriptores de archivo: puede traducir
/dev/fd/NNN
a
He mostrado un ejemplo más complejo para ilustrar múltiples entradas y salidas. Si no necesita leer de la entrada estándar, y la única razón por la que está usando la sustitución del proceso es que el comando requiere un nombre de archivo explícito, simplemente puede usar
/dev/stdin
:Sin , debe usar una tubería con nombre . Una canalización con nombre es una entrada de directorio, por lo que debe crear un archivo temporal en alguna parte, pero ese archivo es solo un nombre, no contiene ningún dato.
/dev/fd/NNN
fuente
</dev/fd/8 >/dev/fd/9
no son equivalentes a<&8 >&9
en Linux y deben evitarse allí.diff <(cat "$2" | xz -d) <(cat "$1" | xz -d)
:?Creo que las canalizaciones con nombre son más fáciles de asimilar que las redirecciones, así que en términos más simples:
p1
yp2
son tuberías temporales con nombre, podrían llamarse cualquier cosa.Sería más inteligente para crear las tuberías en
/tmp
, por ejemplo, en un directorio como Gilles' respuesta espectáculos, y nota que no es necesariocat
aquí, así:(Probablemente también puedas escapar sin las comillas, ya que
mktemp
es probable que cree nombres de archivo "agradables").La solución de tubería tiene la advertencia de que si el comando principal (
diff
) muere antes de leer toda la entrada, los procesos en segundo plano pueden quedar pendientes.fuente
Qué pasa:
fuente