Eu tentei o seguinte comando depois de assistir a este vídeo sobre travessuras de tubos.
man -k . | dmenu -l 20 | awk '{print $1}' | xargs -r man -Tpdf | zathura -
Basicamente, imprime uma lista de páginas de manual no dmenu para que o usuário selecione uma delas, depois usa xargs para executar man -Tpdf %
(imprima para stdout um pdf do manpage git a partir da entrada do xargs) e passe o pdf para um leitor de pdf (zathura )
O problema é que (como você pode ver no vídeo) o leitor de PDF é iniciado antes mesmo de selecionar uma página de manual no dmenu. E se eu clicar em Esc e selecionar nenhum, o leitor de pdf ainda estará aberto, sem nenhum documento.
Como posso fazer com que o leitor de pdf (e qualquer outro comando em uma cadeia de tubulação) seja executado apenas quando sua entrada chegar ao final do arquivo ou quando receber uma entrada? Ou, alternativamente, como posso fazer uma cadeia de tubulações parar depois que um dos comandos encadeados retorna um status de saída diferente de zero (para que, se o dmenu retorne um erro por não selecionar uma opção, os seguintes comandos não sejam executados)?
fonte
pipefail
opção do bash mencionada na resposta de Kusalandanda.Respostas:
Existe
ifne
(no Debian está nomoreutils
pacote):No seu caso:
fonte
moreutils
) deveria ter sido no Unix original e especificado pelo POSIX ... É uma ferramenta tão básica e Unix-ish ...ifne
é um pouco enganadora. O Unix não possui operação "pipe peek", portantoifne
deve realmente ler pelo menos um byte antes de decidir executar o comando dependente. Isso significa que ele não pode apenas fazer o teste e executar o comando, mas deve criar outro canal, bifurcar outro processo para executar o comando dependente e copiar todo o fluxo do canal stdin para o canal a jusante. Se o caso "entrada vazia" não for comum,ifne
pode custar mais recursos do que economiza, em média.Arquivos PDF devem ser procurados; qualquer visualizador de pdf terá que olhar primeiro no trailer e daí saltar para as compensações da tabela refex.
Como os pipes não são procuráveis,
zathura
está usando um truque ofuscante, onde está copiando toda a entrada para um arquivo temporário e, em seguida, use esse arquivo temporário normalmente. Esse tipo de truque "inteligente" está criando falsas esperanças e está levando as pessoas a supor que os arquivos pdf são fáceis de executar.Mas de qualquer maneira,
zathura
realmente faz de espera para o EOF antes de exibir o documento, você não precisa fazer nada para que isso hapen:O problema é que
zathura
não há opção de abrir a janela apenas se o arquivo estiver OK e sair com um erro se esse não for o caso - ele permanecerá lá como se estivesse tudo bem:Portanto, mesmo se você estiver redirecionando a saída para um arquivo temporário e estiver executando apenas
zathura
se tudo estiver OK, não há garantia de que o usuário não será servido com uma janela preta sezathura
não gostar da saída por um motivo ou outro .Btw,
exibirá uma página de manual em uma janela X11
gxditview
, mesmo que pareça diretamente do '70 ;-)E, é claro, você sempre pode usar:
que, além de muitos outros aprimoramentos, permite usar expressões regulares em pesquisas e seleção de texto adequada.
fonte
Todos os comandos em um pipeline iniciam praticamente ao mesmo tempo. É apenas a E / S sobre o canal que as sincroniza. Além disso, um tubo pode conter apenas a informação que o buffer do tubo permitir.
Portanto, não é possível evitar a execução de um estágio de um pipeline, porque
Em vez disso, grave a saída em um arquivo enquanto deixa o pipeline terminar. Então use esse arquivo.
Exemplo (como uma função que aceita um argumento):
Além disso, isso não executaria o
zathura
programa se o pipeline falhasse (axargs
parte retornou diferente de zero) ou o arquivo gerado estivesse vazio.No
bash
shell, você também pode definir apipefail
opção de shellset -o pipefail
para que o pipeline retorne o status de saída do primeiro comando no pipeline que falhar. E você gostaria de fazer atmpfile
variávellocal
:Isso define a
pipefail
opção para a duração da função, se ainda não estiver definida, e a desativa, se necessário. Ele se livra do-s
teste no arquivo de saída.fonte
rm -f
? Você está pensando em casos em que o canal altera as permissões do arquivo tmp?rm -f
não erro se o arquivo já foi removido (possivelmente porzathura
, eu não sei).pipefail
opção funciona como esperado (e no zsh também, que possui a mesma opção).