Algunos shells, como bash
, admiten la sustitución de procesos, que es una forma de presentar la salida del proceso como un archivo, como este:
$ diff <(sort file1) <(sort file2)
Sin embargo, esta construcción no es POSIX y, por lo tanto, no es portátil. ¿Cómo se puede lograr la sustitución del proceso de una manera amigable con POSIX (es decir, una que funcione /bin/sh
) ?
nota: la pregunta no es cómo diferenciar dos archivos ordenados, ¡eso es solo un ejemplo artificial para demostrar la sustitución del proceso !
shell
pipe
posix
process-substitution
starfry
fuente
fuente
/bin/sh
ser un shell POSIX, solo que haya un comando llamado ensh
algún lugar que, en el entorno correcto, sea compatible con POSIX. Por ejemplo, en Solaris 10,/bin/sh
no es un shell POSIX, es un antiguo shell Bourne y el shell POSIX está dentro/usr/xpg4/bin/sh
.Respuestas:
Esa característica fue introducida por
ksh
(documentada por primera vez en ksh86) y estaba haciendo uso de la/dev/fd/n
característica (agregada de forma independiente en algunos sistemas BSD y AT&T anteriormente). Enksh
y hasta ksh93u, no funcionaría a menos que su sistema tuviera soporte para / dev / fd / n. zsh, bash yksh93u+
superiores pueden hacer uso de canalizaciones con nombre temporales (canalizaciones con nombre agregadas en SysIII, creo) donde / dev / fd / n no están disponibles.En los sistemas donde está disponible (POSIX no los especifica), puede realizar la sustitución del proceso usted mismo ( ) con:
/dev/fd/n
diff <(cmd1) <(cmd2)
Sin embargo, eso no funciona
ksh93
en Linux, ya que las tuberías de shell se implementan con pares de sockets en lugar de tuberías y la apertura/dev/fd/3
donde fd 3 apunta a un socket no funciona en Linux.Aunque POSIX no especifica . Sí especifica tuberías con nombre. Las canalizaciones con nombre funcionan como las canalizaciones normales, excepto que puede acceder a ellas desde el sistema de archivos. El problema aquí es que debe crear archivos temporales y limpiar después, lo cual es difícil de hacer de manera confiable, especialmente teniendo en cuenta que POSIX no tiene un mecanismo estándar (como el que se encuentra en algunos sistemas) para crear archivos o directorios temporales, y hacer el manejo de la señal de manera portátil (para limpiar al colgar o matar) también es difícil de hacer de forma portátil.
/dev/fd/n
mktemp -d
Podrías hacer algo como:
(no cuidar el manejo de la señal aquí).
fuente
/dev/fd/n
ejemplo. ¿Por qué el descriptor 4 se cierra dos veces? (Y también lo es el descriptor 3.) Estoy perdido.cmd2
(dup2(0,4)
en el exterior{...}
, restaurado condup2(4,0)
el interior{...}
).mktemp -d
para asegurarse de que puede obtener FIFO, ya que nadie debería escribir en su nuevo directorio temporal aleatorio.mktemp -d
. Pero ese no es un comando estándar / POSIX.Si es necesario para evitar la variable perdida en lo útil
cmd | while read A B C
, en lugar de:puedes usar:
Entonces para responder la pregunta:
fuente