24 votos

Pasar una tubería a un comando que espera un nombre de archivo

Digamos que tengo una orden foo que toma un argumento de nombre de archivo: foo myfile.txt . Molesto, foo no lee de la entrada estándar. En lugar de un archivo real, me gustaría pasarle el resultado de otro comando (en realidad, pv que catará el archivo y mostrará un medidor de progreso como efecto secundario).

¿Hay alguna manera de hacer que esto suceda? Nada en mi bolsa de trucos parece hacerlo.

( foo en este caso es un script PHP que creo que procesa el archivo secuencialmente).

Estoy usando Ubuntu y Bash

EDITAR Perdón por la descripción del problema un poco confusa, pero aquí está la respuesta que hace lo que quiero:

pv longfile.txt | foo /dev/stdin

Muy obvio ahora que lo veo.

0 votos

¿Buscas una frase única?

0 votos

¿Estás seguro de que foo no acepta un argumento de "-" para que lea de stdin?

0 votos

Lamentablemente sí, en este caso - es un php script.

23voto

nullDev Puntos 1778

Si entiendo bien lo que quieres hacer, puedes hacerlo con la función de sustitución de comandos de bash:

foo <(somecommand | pv)

Esto hace algo similar a lo que el mkfifo -excepto que bash maneja los detalles por usted (y termina pasando algo como /dev/fd/63 al comando, en lugar de una tubería normal con nombre). También puedes hacerlo de forma más directa, así:

somecommand | pv | foo /dev/stdin

1 votos

¡Oh, qué bien! Este pv inputfile.txt | foo /dev/stdin es exactamente lo que estaba buscando, pero no se me ocurrió.

0 votos

¡Woot! /dev/stdin

0 votos

<(.) me ha funcionado. ¿Está documentada esta sintaxis en el manual de Bash? Entiendo que (.) como sustitución de comandos está documentado, pero no vi su combinación con < explicada.

2voto

Alex Puntos 104

Esta pregunta de Unix SE tiene una respuesta que muestra cómo crear una tubería temporal con nombre:

Shell ShellscriptShell mktemp, ¿cuál es el mejor método para crear una tubería temporal con nombre?

Basándose en las respuestas de allí, podría hacer algo como lo siguiente:

tmppipe=$(mktemp -u)
mkfifo -m 600 "$tmppipe"
pv examplefile > $tmppipe

A continuación, podría ver la tubería con:

foo $tmppipe

Luego, bórralo cuando hayas terminado con él.

2voto

Hyppy Puntos 11996
ARRAY=(`pv whatever`); for FILE in $ARRAY; do foo $FILE; done

1voto

becomingwisest Puntos 2628

Intenta usar mkfifo.

mkfifo file_read_by_foo; pv ... > file_read_by_foo 

En otro Shell, ejecuta foo file_read_by_foo

0voto

MadHatter Puntos 44059

xargs parece funcionar bien para esto:

echo longfile.txt | xargs pv

0 votos

Eso hace algo diferente: correr pv varias veces, cada una con una o más líneas trazadas desde longfile.txt . No es en absoluto lo que busco aquí.

EnMiMaquinaFunciona.com

EnMiMaquinaFunciona es una comunidad de administradores de sistemas en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros sysadmin, hacer tus propias preguntas o resolver las de los demás.

Powered by: