Como obter rapidamente a saída de linha anterior em um terminal sem usar um mouse?

12

Linux (por exemplo, Ubuntu) terminal, existe um método para obter a última linha? Digamos que eu esteja digitando aleatoriamente um comando td , que não foi instalado no meu sistema, então receberei uma mensagem como abaixo. Eu gostaria de ter um "atalho" para executar sudo apt-get install textdraw rapidamente.

Existe tal ferramenta ou como posso copiar a última linha para a área de transferência sem usar o mouse?

username@WorkStation:~$ td
The program 'td' is currently not installed. You can install it by typing:
sudo apt-get install textdraw
username@WorkStation:~$
    
por Daniel 28.12.2015 / 03:33

5 respostas

5

Se você não se importa com um pouco de obscenidade (eu não sei), você pode querer usar o porra , um ferramenta que faz exatamente o que você pediu.

Bem, não exatamente, mas resolve o mesmo problema. Em vez de apenas obter a última linha, ele tenta corresponder ao último comando digitado.

The Fuck tries to match a rule for the previous command, creates a new command using the matched rule and runs it.

Os exemplos mostrados no repositório mostram vários dos cenários que você mencionou.

    
por 29.12.2015 / 02:33
2

A resposta curta: não, provavelmente você não tem um método disponível para fazer isso.

A resposta longa:

  • enquanto é possível ter um emulador de terminal que permite "apenas" ler o conteúdo da tela e editá-lo, na prática isso não é feito com frequência devido a preocupações de que algum programa indesejado pode bisbilhotar suas entradas de teclado.
  • um shell poderia ser projetado capturar a saída de seus comandos e permitir que você edite isso (assim como seu histórico de comandos). Ficaria complicado se o comando fosse algo como vi (onde a saída não é um texto orientado a linhas). o bash não faz isso, de qualquer maneira.

Na prática, o que as pessoas fazem para contornar essa limitação é usar outros programas para capturar a saída de comando e editá-la. Mas isso não vai resolver seu problema imediato.

Por exemplo, eu uso o vi-like-emacs para emitir comandos shell ad hoc. Se isso não exigir mais informações, funcionará bem para executá-las em uma janela , capturando saída do comando - e editando a saída conforme necessário para refinar o comando. O Emacs também permite que você faça algo assim, assim como o vim.

    
por 28.12.2015 / 10:11
2

Se você recebeu essa mensagem no Ubuntu depois de executar um comando não existente do bash, seu sistema provavelmente está usando a função command_not_found_handle . Você pode ver em /etc/bash.bashrc .

Um hacker trivial pode ser uma opção: Acabei de criar um script chamado cnfh :

#!/bin/bash

# if the command-not-found package is installed, use it
if [ -x /usr/lib/command-not-found -o -x /usr/share/command-not-found/command-not-found ]; then
        function command_not_found_handle {
                # check because c-n-f could've been removed in the meantime
                if [ -x /usr/lib/command-not-found ]; then
                   /usr/lib/command-not-found -- "$1"
                   return $?
                elif [ -x /usr/share/command-not-found/command-not-found ]; then
                   /usr/share/command-not-found/command-not-found -- "$1"
                   return $?
                else
                   printf "%s: command not found\n" "$1" >&2
                   return 127
                fi
        }
fi


"$@"
RET_VAL=$?
if [ $RET_VAL -eq 127 ]; then
  OUT=$(command_not_found_handle "$@" 2>&1)
  $(echo $OUT |sed -n 's/.*\(apt-get install .\+\)$//p')
fi

Em seguida, execute o comando td usando este script:

# ./cnfh td

Usando o Ubuntu 14.04.2 LTS . Espero que ajude.

    
por 28.12.2015 / 15:41
2

No tmux v2.4 e posteriores (desde que este link ) seja confirmado por send-keys -X . Pode ser possível em versões mais antigas, com uma sintaxe diferente.

Em .tmux.conf :

bind ! copy-mode \;\
       send-keys -X cursor-up \;\
       send-keys -X select-line \;\
       send-keys -X cursor-left \;\
       send-keys -X copy-selection-and-cancel \;\
       paste-buffer

Agora, prefix+! copiará a última linha na posição atual do cursor.

cursor-left pode ser deixado de fora se você quiser executá-lo diretamente sem digitar o retorno.

Nota : não funcionará se a última linha estiver vazia ou se estiver envolvida, mas ainda assim é útil na maioria dos casos

    
por 15.03.2017 / 16:07
0

Para executar a última linha de saída do comando mais recente, se você estiver disposto a reexecutar esse comando (como não fez nada além de emitir uma mensagem de diagnóstico), faça

$($(fc -ln -1) | tail -n 1)

Passo a passo (camada por camada):

  • fc (que pode significar "Fix Command") é um comando interno do shell para acessar o histórico de comandos.

    • %código%
      • -ln (letra minúscula L) - l é o (s) comando (s) anterior (es)
      • l - não inclui o comando n umbers
    • n (um) - refere-se ao comando mais recente

    1 lista o comando mais recente, não incluindo um número de comando.

  • fc -ln -1 executa o comando mais recente.
  • $(fc -ln -1) executa o comando mais recente e exibe a última linha de sua saída. Esta é a linha $(fc -ln -1) | tail -n 1 , no seu exemplo.
  • sudo apt-get install textdraw executa o comando .

Você pode usar esse apelido:

alias execute_last_line_of_output_from_previous_command='$($(fc -ln -1) | tail -n 1)'

Deixo para você escolher um nome mais curto para o alias.

Notas:

  • Isso funciona apenas para comandos simples - Nenhum caractere especial como $($(fc -ln -1) | tail -n 1) , | , < , > , ; ou até mesmo aspas. Se você precisa lidar com comandos complexos, você provavelmente pode fazer isso adicionando um & , mas isso não é amplamente recomendado.
  • Se você precisar acessar algo diferente da última linha de saída (por exemplo, a décima sétima a última linha), você pode fazer alguma coisa na linha eval .
  • Se você precisar acessar algo diferente do comando mais recente, você pode alterar os argumentos para tail -n 17 | head -n 1 . Observe que fc é a abreviação de fc -ln -1 . Para recuperar o terceiro comando mais recente, use fc -ln -1 -1 .
  • Se você precisar de flexibilidade como o acima, você provavelmente deveria escrever uma função de shell que aceita argumentos em vez de um alias.
por 07.01.2016 / 20:02