Eu sei que posso executar o último comando no bash, com !!
, mas como posso executar a última linha de saída?
Estou pensando no caso de uso desta saída:
The program 'git' is currently not installed. You can install it by typing:
sudo apt-get install git
Mas não sei como posso fazer isso. Estou pensando em algo como o !!
, talvez @@
ou similar?
command_not_found_handle
função shell ou um script que ele executa (geralmente apenas/usr/lib/command-not-found
). Eu acho que você poderia fazê-lo para que você seja solicitado interativamente com a opção de instalar automaticamente o pacote, ou (provavelmente melhor) para que o nome do pacote seja armazenado em algum lugar e possa ser instalado executando um pequeno comando. Isso é diferente o suficiente do que você pediu aqui. Você pode postar uma pergunta separada sobre isso.Respostas:
O comando
$(!! |& tail -1)
deve fazer:Como você pode ver, o
sudo apt-get install git
comando está sendo executado.EDIT: Quebrando
$(!! |& tail -1)
$()
é obash
padrão de substituição de comandobash
expandirá!!
para o último comando executado|&
parte é complicada. Normalmente, o pipe|
pega o STDOUT do comando do lado esquerdo e o passa como STDIN para o comando no lado direito do|
, no seu caso, o comando anterior imprime sua saída no STDERR como uma mensagem de erro. Portanto, fazer|
não ajudaria, precisamos passar o STDOUT e o STDERR (ou apenas STDERR) para o comando do lado direito.|&
passará STDOUT e STDERR como STDIN para o comando do lado direito. Como alternativa, melhor você só pode passar o STDERR:tail -1
como sempre, imprimirá a última linha a partir de sua entrada. Aqui, em vez de imprimir a última linha, você pode ser mais preciso, como imprimir a linha que contém oapt-get install
comando:fonte
TL; DR:
alias @@='$($(fc -ln -1) |& tail -1)'
As instalações de interação do histórico do Bash não oferecem nenhum mecanismo para examinar a saída dos comandos. O shell não armazena isso , e a expansão do histórico é específica para os comandos que você mesmo executou ou para partes desses comandos.
Isso deixa a abordagem de executar novamente o último comando e canalizar stdout e stderr (
|&
) em uma substituição de comando. A resposta de heemayl consegue isso, mas não pode ser usada em um alias porque o shell executa a expansão do histórico antes de expandir os aliases, e não depois.Também não posso fazer com que a expansão do histórico funcione em uma função shell, mesmo ativando-a na função com
set -H
. Eu suspeito que!!
uma função nunca será expandida, e não tenho certeza para o que seria expandida, mas, no momento, não sei exatamente por que não é.Portanto, se você deseja configurar as coisas para que você possa fazer isso com muito pouca digitação, use o
fc
shell interno em vez da expansão do histórico para extrair o último comando do histórico. Isso tem a vantagem adicional de funcionar mesmo quando a expansão do histórico está desativada.Como mostrado na Gordon Davisson 's resposta para criar um apelido contendo expansão história do bash (em Super User ),
$(fc -ln -1)
Simula!!
. Ligar o dentro para!!
no comando do heemayl$(!! |& tail -1)
rendimentos:Isso funciona como,
$(!! |& tail -1)
mas pode ter uma definição de alias:Depois de executar essa definição, colocá-la em
.bash_aliases
ou.bashrc
iniciar um novo shell, você pode simplesmente digitar@@
(ou o que quer que tenha chamado de alias) para tentar executar a última linha de saída do último comando.fonte
./script
, não o que você fornece com.
ousource
embutido - não tenho certeza. O Bash anexa a um arquivo na saída do shell ou quando você executahistory
com-a
ou-w
(consultehelp history
). Se isso acontecesse, os comandos em vários shells interativos seriam intercalados (aparecendo na ordem em que você os executou). Você pode anexá-lo imediatamente. . Mas acho que há mais o que fazer parafc
trabalhar em um script. Sugiro postar uma nova pergunta sobre isso. Se o fizer, sinta-se à vontade para comentar aqui com um link para ele.Se você estiver usando um emulador de terminal no X, como
gnome-terminal
,konsole
ouxterm
, poderá usar a seleção X para algo como copiar e colar:Use a seleção principal
Selecione a linha inteira para executar com um clique esquerdo triplo .
Em seguida, cole-o na linha de comando usando o botão do meio .
Isso deve funcionar na maioria dos emuladores de terminal. Utiliza a seleção primária, sem tocar na área de transferência - elas são separadas.
É selecionar e, em seguida, combinar copiar e colar em uma operação, tecnicamente.
fonte
Como Eliah Kagan mencionou , o shell não armazena a saída do comando. No entanto, existe uma maneira de obter a última linha de saída do último comando, sem executar o comando novamente , se você executar a tela .
Coloque as seguintes linhas em você
~/.screenrc
:Em seguida, você pode pressionar Ctrl+ atpara inserir a linha anterior no prompt atual. Seria possível fazer isso também pressionar automaticamente enter, mas provavelmente é uma idéia melhor verificá-lo antes de executar e pressione enter manualmente.
Como funciona:
register t
registra uma string em um buffer chamadot
. A sequência a seguir é uma sequência de teclas.bind t
vincula à chave t(ou seja, executar usando Ctrl+ at),process t
significa avaliar o conteúdo do buffer nomeadot
.^a[
(= Ctrla[): entra no modo de cópiak
suba uma linha,0
vá para o início da linha,y$
copie até o final da linha, (espaço) complete o comando^a]
(= Ctrla]): cole o conteúdo copiado^a^L
(= CtrlaCtrlL) atualize a tela (caso contrário, o conteúdo colado não será exibido, porque você não o digitoufonte