A menudo quiero alimentar datos de cadenas relativamente cortas (aunque podrían ser varias líneas) a los programas de línea de comandos que aceptan solo la entrada de archivos (por ejemplo, wdiff) de manera repetida. Claro que puedo crear uno o más archivos temporales, guardar la cadena allí y ejecutar el comando con el nombre del archivo como parámetro. Pero me parece que este procedimiento sería muy ineficiente si los datos se escriben realmente en el disco y también podría dañar el disco más de lo necesario si repito este procedimiento muchas veces, por ejemplo, si quiero alimentar líneas individuales de texto largo archivos a wdiff. ¿Hay alguna forma recomendada de evitar esto, por ejemplo, mediante el uso de pseudo archivos como tuberías para almacenar los datos temporalmente sin escribirlos en el disco (o escribirlos solo si exceden una longitud crítica). Tenga en cuenta que wdiff toma dos argumentos y,wdiff <"text"
.
98
xargs
?xargs
, las líneas de entrada de los argumentos de cadena de archivo para el comando. Pero necesito lo contrario.echo $data_are_here | dumb_program
?Respuestas:
Use una tubería con nombre . A modo de ilustración:
El
-e
echo le dice a interpretar correctamente el escape de nueva línea (\n
). Esto bloqueará, es decir, su shell se bloqueará hasta que algo lea los datos de la tubería.Abra otro shell en algún lugar y en el mismo directorio:
Leerás el eco, que liberará el otro shell. Aunque la tubería existe como un nodo de archivo en el disco, los datos que la atraviesan no existen; Todo tiene lugar en la memoria. Puede fondo (
&
) el eco.La tubería tiene un búfer de 64k (en Linux) y, como un zócalo, bloqueará el escritor cuando esté lleno, por lo que no perderá datos mientras no mate prematuramente al escritor.
fuente
/tmp
está configurado en la mayoría de las distribuciones para usar untmpfs
sistema de archivos que está en RAM. Cuando escribe un archivo en/tmp
él, va directamente a su RAM, lo que es una buena respuesta para los archivos semi-resistentes a los que se debe acceder rápidamente y reescribirse muchas veces.En Bash, puede usar la
command1 <( command0 )
sintaxis de redireccionamiento, que redirigecommand0
la salida estándar y la pasa a unacommand1
que toma un nombre de archivo como argumento de línea de comandos. Esto se llama sustitución de proceso .Algunos programas que toman argumentos de la línea de comandos del nombre de archivo realmente necesitan un archivo de acceso aleatorio real, por lo que esta técnica no funcionará para ellos. Sin embargo, funciona bien con
wdiff
:En segundo plano, esto crea un FIFO, canaliza el comando dentro
<( )
del FIFO y pasa el descriptor de archivo del FIFO como argumento. Para ver qué está pasando, intente usarloecho
para imprimir el argumento sin hacer nada con él:Crear una canalización con nombre es más flexible (si desea escribir una lógica de redireccionamiento complicada utilizando múltiples procesos), pero para muchos propósitos esto es suficiente y obviamente es más fácil de usar.
También existe la
>( )
sintaxis para cuando desea usarlo como salida, por ejemploConsulte también la hoja de trucos de redireccionamientos de Bash para conocer las técnicas relacionadas.
fuente
ssh -F <(vagrant ssh-config) default
, sería realmente agradable, pero por desgracia.wdiff es un caso especial debido a que requiere 2 argumentos de nombre de archivo, pero para todos los comandos que solo requieren 1 argumento y que se niegan obstinadamente a tomar cualquier cosa que no sea un argumento de nombre de archivo, hay 2 opciones:
El nombre de archivo '-' (es decir, un signo menos) funciona aproximadamente la mitad del tiempo. Parece depender del comando en cuestión y si el desarrollador del comando atrapa ese caso y lo maneja como se esperaba. p.ej
Hay un archivo psuedo llamado / dev / stdin que existe en Linux y se puede usar si un comando requiere absolutamente un nombre de archivo. Es más probable que funcione, ya que no requiere ningún manejo especial de nombre de archivo del comando. Si un fifo funciona, o el método de sustitución del proceso bash funciona, entonces esto también debería funcionar y no es específico del shell. p.ej
fuente