Intenté el siguiente comando después de ver este video sobre travesuras de tuberías.
man -k . | dmenu -l 20 | awk '{print $1}' | xargs -r man -Tpdf | zathura -
Básicamente imprime una lista de páginas de manual en dmenu para que el usuario seleccione una de ellas, luego usa xargs para ejecutar man -Tpdf %
(imprimir para stdout un pdf del git de página de manual desde la entrada de xargs) y pasar el pdf a un lector de pdf (zathura )
El problema es que (como puede ver en el video) el lector de PDF comienza incluso antes de seleccionar una página de manual en dmenu. Y si hago clic en Esc y no selecciono ninguno, el lector de PDF todavía está abierto y no muestra ningún documento.
¿Cómo puedo hacer que el lector de PDF (y cualquier otro comando en una cadena de tuberías) solo se ejecute cuando su entrada llegue al final del archivo o cuando reciba una entrada? O, alternativamente, ¿cómo puedo hacer que una cadena de tuberías se detenga después de que uno de los comandos encadenados devuelve un estado de salida distinto de cero (de modo que si dmenu devuelve un error por no seleccionar una opción, los siguientes comandos no se ejecutan)?
fuente
pipefail
opción de bash mencionada en la respuesta de Kusalandanda.Respuestas:
Hay
ifne
(en Debian está en elmoreutils
paquete):En tu caso:
fuente
moreutils
) deberían haber estado en el Unix original y especificado por posix ... Es una herramienta tan básica y Unix-ish ...ifne
es un poco engañosa. Unix no tiene ninguna operación de "vistazo de tubería", por lo queifne
debe leer al menos un byte antes de decidir ejecutar el comando dependiente. Eso significa que no solo puede hacer la prueba y ejecutar el comando, sino que debe crear otra tubería, bifurcar otro proceso para ejecutar el comando dependiente y copiar todo el flujo de la tubería estándar a la tubería aguas abajo. Si el caso de "entrada vacía" no es común,ifne
podría costar fácilmente más recursos de los que ahorra, en promedio.Se supone que los archivos PDF son buscables; cualquier visor de PDF tendrá que mirar primero el avance y, a partir de ahí, saltar a los desplazamientos de la tabla xref.
Dado que las tuberías no son buscables,
zathura
está utilizando un truco de ofuscación, donde está copiando toda la entrada a un archivo temporal, y luego usa ese archivo temporal como de costumbre. Este tipo de truco "inteligente" está creando falsas esperanzas y está llevando a las personas a suponer que los archivos pdf son transmisibles.Pero de todos modos,
zathura
realmente lo hace espera para el EOF antes de mostrar el documento, usted no tiene que hacer nada para que eso hapen:El problema es que
zathura
no tiene la opción de abrir la ventana solo si el archivo está bien y salir con un error si ese no es el caso; simplemente permanecerá allí como si todo estuviera bien:Entonces, incluso si está redirigiendo la salida a un archivo temporal usted mismo, y solo se está ejecutando
zathura
si todo estaba bien, no hay garantía de que el usuario no reciba una ventana negra sizathura
no le gusta la salida por una razón u otra .Por cierto,
mostrará una página de manual en una ventana X11 con
gxditview
, incluso si se ve directamente desde el '70 ;-)Y, por supuesto, siempre puedes usar:
que, además de muchas otras mejoras, le permitirá usar expresiones regulares en las búsquedas y la selección de texto adecuada.
fuente
Todos los comandos en una tubería comienzan casi al mismo tiempo. Es solo la E / S sobre la tubería que los sincroniza. Además, una tubería solo puede contener tanta información como lo permita el búfer de la tubería.
Por lo tanto, no puede evitar ejecutar una etapa de una tubería, porque
En su lugar, escriba la salida en un archivo mientras deja que finalice la canalización. Luego usa ese archivo.
Ejemplo (como una función que toma un argumento):
Además, esto no ejecutaría el
zathura
programa si la canalización fallara (laxargs
parte devuelta no es cero) o el archivo generado está vacío.En el
bash
shell, también puede configurar lapipefail
opción del shellset -o pipefail
para que la tubería devuelva el estado de salida del primer comando en la tubería que falla. Y querrías hacer latmpfile
variablelocal
:Esto establece la
pipefail
opción para la duración de la función, si aún no estaba configurada, y luego la desarma si es necesario. Se deshace de la-s
prueba en el archivo de salida.fuente
rm -f
? ¿Está pensando en casos en los que la tubería cambia los permisos del archivo tmp?rm -f
no se produciría un error si el archivo ya se eliminó (posiblementezathura
, no lo sé)pipefail
opción funciona como se esperaba (y también en zsh, que tiene la misma opción).