Costumo usar find
ou locate
para descobrir caminhos.
(~) locate foobar.mmpz
/home/progo/lmms/projects/foobar.mmpz
O próximo passo é frequentemente abrir ou manipular os arquivos. Em um caso feliz como acima, eu posso fazer isso:
(~) ls `!!`
ls `locate foobar.mmpz`
/home/progo/lmms/projects/foobar.mmpz
Mas ninguém fica muito feliz quando há muitas linhas de saída, algumas das quais podem não ser caminhos ou algo desse tipo. Além disso, reexecutar comandos potencialmente inúteis também não é tão elegante.
Haveria uma maneira de conectar o zsh para armazenar o stdout em uma matriz para manipulação posterior? Afinal, o trabalho do shell é redirecionar os fluxos para o usuário. Eu estou pensando que poderia armazenar a primeira N e a última N linhas em uma variável para uso imediato imediato, como $?
e outras.
Ok, então isso é bem legal: /unix//a/59704/5674 . Agora estou perguntando sobre o know-how do zsh (e portando o código para o zsh) para manipular esse tipo de captura após cada linha de execução.
screen
orscript
e precmd e preexec.Respostas:
Não há recurso para capturar a saída da tela na maioria dos emuladores de terminal. Eu me lembro do autor do xterm (o emulador de terminal de "referência") afirmando que seria difícil de implementar. Mesmo se isso fosse possível, o shell teria que rastrear onde estava o último prompt.
Portanto, você não deixará de executar o comando novamente, a menos que use um mecanismo manual específico do terminal, como colar e colar com o mouse no xterm ou com o teclado na tela.
Seria altamente impraticável para o shell capturar automaticamente a saída dos comandos, porque não é possível distinguir entre comandos que possuem complexas interações entre terminal e usuário e comandos que simplesmente produzem caracteres imprimíveis.
Você pode executar novamente o comando e capturar sua saída. Existem várias maneiras de fazer cada uma. Para executar novamente o comando, você pode usar:
!!
substituição de histórico - mais conveniente para digitar;fc -e -
, que pode ser usado em uma funçãoPara capturar a saída, você pode usar a substituição de comandos ou uma função como a seguinte:
Isso define a
lines
matriz para a saída do comando que é canalizado para ela.fonte
K
sua.Aqui está um primeiro corte de algo para colocar a última linha de saída em uma variável chamada
$lastline
.Isso usa o
preexec
gancho do zsh para executarexec
etee
armazena uma cópia do stdout do comando, depois usaprecmd
para ler a saída armazenada e restaurar stdout para ser apenas o terminal para mostrar o prompt.Mas ainda precisa de algum trabalho. Por exemplo, como stdout não é mais um terminal, programas como
vim
eless
não funcionam corretamente.Há algumas informações relacionadas úteis nessas perguntas:
fonte
exec
chamadas no código, o comando está sendo executado várias vezes ou estou preso em semântica especial?exec
sem um nome de programa apenas define redirecionamentos.Você pode fazer isso apenas direcionando seus resultados para
tee
, o que salva a saída em um arquivo e a exibe ao mesmo tempo.Por exemplo, você pode fazer isso, que mostra sua saída normalmente, mas também a salva no arquivo
/tmp/it
locate foobar.mmpz | tee /tmp/it
então cat que arquivo e grep-lo para selecionar as coisas, por exemplo
cat /tmp/it | grep progo | grep lms
então, para usá-lo, você pode fazer o seguinte:
vi $(!!)
fonte
Eu vim com esta solução meia cozida:
Isso permite que você escreva
___
em qualquer ponto da linha de comando. O comando anterior será executado novamente e___
será substituído pela última linha de sua saída. Exemplo de uso:O último comando será expandido para
vim foo
.Isso tem algumas arestas afiadas!
Se você incluir
___
um comando, mas o comando anterior também incluir um___
, o shell ficará travado em um estado estranho por um tempo. Você pode sair desse estado imediatamente com Ctrl- C.Você também não pode pressionar Tabpara expandir o
___
, como pode com!$
e outras construções.Alguns comandos exibem saídas diferentes quando são executados “normalmente” e quando são conectados a um tubo. (Compare a saída de
ls
els | cat
.) Se o comando acionado por___
for um deles, você poderá executar um comando diferente do esperado.E, é claro, se você quiser fazer algo com uma linha de saída diferente da última, isso não ajudará.
Eu escolhi o nome
___
porque é algo que eu nunca quis incluir como palavra em uma linha de comando, nem mesmo como argumento. Você pode escolher um nome diferente, mas tome cuidado para não escolher algo que possa ser expandido para você inadvertidamente.fonte