Às vezes, preciso escrever um texto e depois canalizá-lo para outro comando. Meu fluxo de trabalho usual é mais ou menos assim:
vim
# I edit and save my file as file.txt
cat file.txt | pandoc -o file.pdf # pandoc is an example
rm file.txt
Acho isso complicado e procurando aprender scripts bash, gostaria de tornar o processo muito mais simples, escrevendo um comando que aciona um editor e, quando o editor fecha, direciona a saída do editor para o stdout. Então eu seria capaz de executar o comando como quickedit | pandoc -o file.pdf
.
Não tenho certeza de como isso funcionaria. Eu já escrevi uma função para automatizar isso, seguindo o fluxo de trabalho exato acima, além de algumas adições. Ele gera uma sequência aleatória para atuar como um nome de arquivo e a passa para o vim quando a função é chamada. Quando o usuário sai do vim salvando o arquivo, a função imprime o arquivo no console e exclui o arquivo.
function quickedit {
filename="$(cat /dev/urandom | env LC_CTYPE=C tr -cd 'a-f0-9' | head -c 32)"
vim $filename
cat $filename
rm $filename
}
# The problem:
# => Vim: Warning: Output is not to a terminal
O problema que encontrei logo é que, quando faço algo como o quickedit | command
próprio vim, não pode ser usado como editor, porque toda a saída é restrita ao canal.
Gostaria de saber se existem soluções alternativas para isso, para que eu possa canalizar a saída da minha quickedit
função. A alternativa subótima é acionar um editor separado, digamos texto sublime, mas eu realmente quero ficar no terminal.
:w !pandoc -o file.pdf
? (Nota: o espaço entrew
e!
é essencial.) #mktemp
lo em vez de reinventá-lo de maneira insegura.Respostas:
vipe
é um programa para editar pipelines:Você obtém um editor com a saída completa de
command1
e, quando você sai, o conteúdo é passado paracommand2
o canal.Nesse caso, não há
command1
. Então, você poderia fazer:Ou:
vipe
seleciona as variáveisEDITOR
eVISUAL
, para que você possa usá-las para abrir o Vim.Se você não o instalou,
vipe
está disponível nomoreutils
pacote;sudo apt-get install moreutils
, ou qualquer que seja o equivalente do seu sabor.fonte
moreutils
está disponível no Homebrew.moreutils
está disponível para instalação via pkg (8) .Você pode fazer isso no Vim:
Ou até mesmo grave o buffer em um pipeline complexo:
E então você pode sair do Vim sem salvar:
No entanto, considerando seu caso de uso específico, provavelmente há uma solução melhor usando
vi
como seu editor de linha de comando. Supondo que você usebash
:Isso define suas combinações de teclas para
vi
. Assim você pode editar seus comandos à direita na linha de comando com basevi
keybindings pressionando<Esc>
e digitandovi
comandos comox
,cw
, etc. (Você pode voltar no modo de inserção pressionandoi
.)Ainda melhor e mais relevante para essa pergunta, você pode abrir o Vim para criar diretamente o conteúdo da linha de comando. Basta digitar
<Esc>v
e você obterá um buffer Vim vazio. Quando você salva e sai, esse é o comando na sua linha de comandos e é executado imediatamente. Isso é muito mais flexível do que editar diretamente na linha de comando, pois você pode escrever um mini-script inteiro, se desejar.Portanto, por exemplo, se você quiser escrever um texto complicado e inseri-lo no pandoc imediatamente, basta digitar:
Em seguida, edite o buffer do Vim até obter algo como:
Em seguida, salve e saia (com
:x
) e a coisa toda será executada como um comando shell.Também estará disponível no histórico de comandos do seu shell.
fonte
EDITOR
variável de ambientevim
e pressionandoCtrl-X
seguido porCtrl-E
enquanto edita a linha de comando.Executando em um pipeline
Experimentar:
A chave é que, para poder usar
vim
normalmente, ovim
stdout precisa ser o terminal. Conseguimos isso aqui com o redirecionamento>/dev/tty
.Por questões de segurança, coloquei o arquivo temporário no diretório inicial do usuário. Para mais informações, consulte a Pergunta 062 de Greg's FAQ . Isso elimina a necessidade de usar um nome de arquivo obscuro.
Exemplo:
Quando
vim
abre, digitoThis function succeeded.
e salvo o arquivo. O resultado na tela se parece com:Embora a saída de
quickedit
seja redirecionada para um pipeline,vim
ainda funciona normalmente porque fornecemos acesso direto a ela/dev/tty
.Executando um programa no vim
Como mencionei nos comentários, o vim pode canalizar um arquivo para um comando. No vim, por exemplo, emita o comando
:w !pandoc -o file.pdf
(Nota: o espaço entre w e! É essencial).fonte
trap '...' exit
falha mastrap '...' EXIT
parece funcionar. Não sei muito sobre interceptação, mas minha abordagem geral para arquivos temporários é usarmktmp [--suffix=...]
. Além disso,vim <outfile> -c '...' >/dev/tty
é executado normalmente até o arquivo ser carregado e, em seguida, executa a cadeia de comandos fornecida, inclusive:wq
se você deseja pular a fase de edição. Eu também useiset | grep -a EXIT
e encontreisignals=(EXIT ... DEBUG)
.Certifique-se de que
vim
está definido como seu editor padrão (por exemplo,export EDITOR=vim
no seu.bash_profile
ou.bashrc
. Então, a qualquer momento, você pode digitar Ctrl- Xseguido de Ctrl- E. Isso abrirá sua linha de comando atual no seu editor configurado (por exemplovim
). Faça suas edições, salve e exit e o comando será executado como se você o tivesse digitado na linha de comando, incluindo pipelines e similares.fonte