Un comando tar normal
tar cvf foo.tar ./foo >foo.out 2>foo.err
tiene tres flujos de salida de E / S
- archivar datos en foo.tar
- lista de nombres de archivo a STDOUT (redirigido a foo.out)
- mensajes de error a STDERR (redirigido a foo.err)
Luego puedo inspeccionar foo.err en busca de mensajes de error sin tener que leer la lista de nombres de archivo.
si quiero hacer algo con los datos del archivo (canalizarlos a través de netcat o un programa de compresión especial), puedo usar la -f -
opción tar
tar cvf - ./foo 2>foo.err | squish > foo.tar.S
Pero ahora mi lista de nombres de archivo se mezcla con mis mensajes de error porque la -v
salida de tar obviamente no puede ir a STDOUT (ahí es donde fluyen los datos del archivo), por lo que tar escribe ingeniosamente en STDERR.
Usando el shell Korn, ¿hay alguna manera de construir un comando que canalice la secuencia de archivo a otro comando pero aún así capture la -v
salida por separado de cualquier mensaje de error.
tee
? Esto parece un caso de uso bastante válido para ello.Respuestas:
Si su sistema admite
/dev/fd/n
:Que con las implementaciones de AT&T de
ksh
(bash
oozsh
) podría escribir usando la sustitución de procesos :Eso está haciendo exactamente lo mismo, excepto que esta vez, el shell decide qué descriptor de archivo usar en lugar de
3
(generalmente por encima de 9). Otra diferencia es que esta vez, obtienes el estado de salida de entar
lugar desquish
. En los sistemas que no son compatibles/dev/fd/n
, algunos shells pueden recurrir a canalizaciones con nombre para esa característica.Si su sistema no es compatible
/dev/fd/n
o su shell no puede hacer uso de canalizaciones con nombre para su sustitución de procesos, ahí es donde tendrá que lidiar con las canalizaciones con nombre a mano .fuente
Tienes que usar una tubería con nombre para eso.
Primero cree uno en la carpeta:
Luego usa ese comando:
Aviso: la parte
cat
, ahora también puede sergzip
o lo que sea, que se puede leer desde una tubería:Explicación:
La salida se escribe en el tubo de nombre (
foo.pipe
), donde otro proccess (cat
,gzip
,netcat
) lee de. Por lo tanto, no pierde los canales stdout / stderr para obtener información.fuente
umask 077
(o usar un directorio temporal privado) para evitar que otros procesos lean o escriban en él (en muchos sistemas, las canalizaciones con nombre, como otros archivos se crean de forma legible por mundo), 2) necesita asegurarse el conducto con nombre solo lo usa cada instancia de su script (de nuevo, un directorio temporal privado único ayuda) 3) Eso significa que necesita limpiar después o si se interrumpe.p="/tmp/pipe$$"; mkfifo "$p"; (read na; cmd[s]...) <>"$p" & (echo;rm "$p"; cmd[s]...) >"$p"
La
--index-file
opción de GNU tar funciona bien:fuente