J'ai essayé la commande suivante après avoir regardé cette vidéo sur les manigances de tuyaux.
man -k . | dmenu -l 20 | awk '{print $1}' | xargs -r man -Tpdf | zathura -
Il imprime essentiellement une liste de pages de manuel dans dmenu pour que l'utilisateur en sélectionne une, puis il utilise xargs pour exécuter man -Tpdf %
(imprimer pour sortir un pdf de la page de manuel git à partir de l'entrée de xargs) et passer le pdf à un lecteur pdf (zathura ).
Le problème est que (comme vous pouvez le voir dans la vidéo) le lecteur pdf démarre avant même que je sélectionne une page de manuel dans dmenu. Et si je clique sur Échap et que je n'en sélectionne aucun, le lecteur pdf est toujours ouvert et ne montre aucun document.
Comment puis-je faire en sorte que le lecteur PDF (et toute autre commande d'une chaîne de tuyaux) ne s'exécute que lorsque son entrée atteint une fin de fichier ou lorsqu'il reçoit une entrée? Ou bien, comment puis-je faire en sorte qu'une chaîne de tuyaux s'arrête après qu'une des commandes chaînées renvoie un état de sortie non nul (de sorte que si dmenu renvoie une erreur pour ne pas avoir sélectionné une option, les commandes suivantes ne sont pas exécutées)?
la source
pipefail
option de bash mentionnée dans la réponse de Kusalandanda.Réponses:
Il y a
ifne
(dans Debian c'est dans lemoreutils
paquet):Dans ton cas:
la source
moreutils
) aurait dû être dans l'Unix d'origine et spécifiée par posix ... C'est un outil tellement basique et Unix-ish ...ifne
est un peu trompeuse. Unix n'a pas d'opération "pipe peek", ilifne
doit donc lire au moins un octet avant de décider d'exécuter la commande dépendante. Cela signifie qu'il ne peut pas simplement faire le test et exécuter la commande, mais doit créer un autre canal, bifurquer un autre processus pour exécuter la commande dépendante et copier tout le flux du canal stdin vers le canal en aval. Si le cas «entrée vide» n'est pas courant, ilifne
pourrait facilement coûter plus de ressources qu'il n'en économise, en moyenne.Les fichiers PDF sont censés être recherchés; tout lecteur de PDF devra d'abord regarder la bande-annonce et de là, passer aux décalages de la table xréf.
Étant donné que les canaux ne sont pas recherchés,
zathura
utilise une astuce d'obscurcissement, où il copie toutes les entrées dans un fichier temporaire, puis utilise ce fichier temporaire comme d'habitude. Ce genre de truc «intelligent» crée de faux espoirs et amène les gens à supposer que les fichiers pdf sont diffusables.Mais de toute façon,
zathura
vraiment fait attendre l'EOF avant d' afficher le document, vous ne devez rien faire pour que cela se Hapen:Le problème est qu'il
zathura
n'a pas la possibilité d'ouvrir uniquement la fenêtre si le fichier est OK et de quitter avec une erreur si ce n'est pas le cas - il y restera comme si tout allait bien:Donc, même si vous redirigez vous-même la sortie vers un fichier temporaire et que vous ne courez que
zathura
si tout était OK, rien ne garantit que l'utilisateur ne sera pas prévenu d'une fenêtre noire s'ilzathura
n'aime pas la sortie pour une raison ou une autre .Btw,
affichera une page de manuel dans une fenêtre X11 avec
gxditview
, même si elle semble tout droit sortie du '70 ;-)Et, bien sûr, vous pouvez toujours utiliser:
qui, en plus de nombreuses autres améliorations, vous permettra d'utiliser des expressions régulières dans les recherches et la sélection de texte appropriée.
la source
Toutes les commandes d'un pipeline démarrent à peu près en même temps. Ce ne sont que les E / S sur le canal qui les synchronisent. En outre, un tuyau ne peut contenir autant d'informations que le tampon du tuyau le permet.
Vous ne pouvez donc pas éviter d'exécuter une étape d'un pipeline, car
Au lieu de cela, écrivez la sortie dans un fichier tout en laissant le pipeline se terminer. Utilisez ensuite ce fichier.
Exemple (en tant que fonction prenant un argument):
De plus, cela n'exécuterait pas le
zathura
programme si le pipeline échouait (laxargs
partie renvoyée non nulle) ou si le fichier généré était vide.Dans le
bash
shell, vous pouvez également définir l'pipefail
option shell avecset -o pipefail
pour que le pipeline renvoie l'état de sortie de la première commande du pipeline qui échoue. Et vous voudriez faire latmpfile
variablelocal
:Cela définit l'
pipefail
option pour la durée de la fonction, si elle n'était pas déjà définie, puis la désactive si nécessaire. Il supprime le-s
test sur le fichier de sortie.la source
rm -f
? Envisagez-vous des cas où le canal modifie les autorisations du fichier tmp?rm -f
ne ferait pas d'erreur si le fichier a déjà été supprimé (éventuellement parzathura
, je ne sais pas).pipefail
option fonctionne comme prévu (et dans zsh aussi, qui a la même option).