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


13

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

Existe essa 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:~$

Pressione a seta para cima? Você já tentou isso? Verifique também o comando history no Linux, que também pode funcionar para você.
Richie086

Os programas multiplexadores de terminal, tmux e screen, fornecem a capacidade de obter texto em uma área de transferência. No entanto, pode haver uma maneira mais fácil na GUI padrão do Ubuntu, então suspeito que uma resposta mais fácil possa estar disponível. Pressionar PgUp, Shift-PgUp ou Ctrl-PgUp pode permitir a rolagem.
TOOGAM

3
@ Richie086 Por favor note, o que eu preciso é sudo apt-get install textdraw, não td. seta para cima só vai me dar o #td
284 Daniel Daniel

Respostas:


6

Se você não se importa com um pouco de obscenidade (eu não), convém usar essa porra , uma 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.

O Fuck tenta corresponder uma regra para o comando anterior, cria um novo comando usando a regra correspondente e a executa.

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

insira a descrição da imagem aqui


2

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

A resposta longa:

  • embora seja possível ter um emulador de terminal que permita "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 possa bisbilhotar as entradas do teclado.
  • um shell pode ser projetado para capturar a saída de seus comandos e permitir que você edite isso (assim como seu histórico de comandos). Seria complicado se o comando fosse algo como vi(onde a saída não é um bom texto orientado a linhas). bash não faz isso, de qualquer maneira.

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

Por exemplo, eu uso o vi-like-emacs para emitir comandos ad hoc shell. Se esses itens não exigirem entrada adicional, funcionará bem em executá-los em uma janela , capturando a 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.


2

Se você recebeu essa mensagem no ubuntu depois de executar um comando inexistente do bash, seu sistema provavelmente está usando a command_not_found_handlefunção. Você pode vê-lo /etc/bash.bashrc.

Um hacking 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 .\+\)$/\1/p')
fi

Em seguida, execute o comando td usando este script:

# ./cnfh td

Usando o Ubuntu 14.04.2 LTS . Espero que ajude.


Parece muito legal e talvez algo que eu gostaria de adicionar ao meu sistema. Você poderia adicionar algumas informações sobre como isso funciona? O código interno para lidar com conclusões e coisas assim é muito difícil de entender.
Joe

2

No tmux v2.4 e posteriores (desde que este commit https://github.com/tmux/tmux/commit/76d6d3641f271be1756e41494960d96714e7ee58 ) com 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 return.

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


1

Para executar a última linha de saída do comando mais recente, se você desejar executar novamente esse comando (já que ele não fez nada, exceto 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.

    • -ln
      • l(minúsculas L) - l ist comando anterior (s)
      • n- não incluem comando n umbers
    • 1 (um) - refere-se ao comando mais recente

    fc -ln -1 lista o comando mais recente, sem incluir um número de comando.

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

Você pode alias isso:

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

Deixo a você escolher um nome mais curto para o apelido.

Notas:

  • Isso só funciona para comandos simples - sem caracteres especiais como |, <, >, ;, &, ou até mesmo citações. Se você precisar manipular comandos complexos, provavelmente poderá fazê-lo adicionando um eval, mas isso não é recomendado.
  • Se você precisar acessar algo diferente da última linha de saída (por exemplo, a décima sétima para a última linha), poderá fazer alguma linha tail -n 17 | head -n 1.
  • Se você precisar acessar algo diferente do comando mais recente, poderá alterar os argumentos para fc. Observe que fc -ln -1é a abreviação de fc -ln -1 -1. Para recuperar o terceiro comando mais recente, use fc -ln -3 -3.
  • Se você precisar de flexibilidade como a acima, provavelmente deverá escrever uma função shell que use argumentos em vez de um alias.
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.