Como copiar uma linha de comando inteira na minha área de transferência, sem o mouse?

20

Imagine que eu tenho essa linha no meu terminal:

youtube-dl --get-thumbnail --extract-audio --audio-format mp3 https://www.youtube.com/watch?v=

Depois de testá-lo, gostaria de copiar esta linha acima para a minha área de transferência e colá-la em algum arquivo de script. Não é a saída do comando . Mas, fazendo isso sem usar o mouse. Eu gosto de manter minhas mãos apenas no teclado. Eu acho que é mais rápido assim, para fazer alguma codificação :)

Valter Silva
fonte

Respostas:

22

Minha resposta oferece um comando simples em três sintaxes diferentes, que funcionam igualmente, mas uma é um pouco mais curta e mais fácil de digitar que a segunda. A terceira variação é um apelido, ou seja, você pode atribuir um nome personalizado ao comando e chamá-lo executando isso sem precisar se lembrar de coisas complexas.

Preparação:

Primeiro, instale o pacote xselque permite acessar a área de transferência do X a partir do terminal:

sudo apt-get install xsel

Variação de comando 1 (curta):

Depois disso, você pode digitar a seguinte linha para copiar o comando anterior para a área de transferência:

xsel -ib <<<!!:q

Se você deseja copiar o segundo comando mais recente, substitua !!por !-2, pelo terceiro uso mais recente !-3e assim por diante.

Para explicar o que você está executando, aqui está um breve detalhamento do comando:

  • xselé uma ferramenta de linha de comando para acessar as pranchetas do X.
    Para obter mais informações, leia a página de manual onÍcone da página de manual - line ou executando man xsel.

    • O -iparâmetro diz xselpara ler a partir do stdin (geralmente isso significa entrada do teclado, mas vamos redirecionar algo aqui)
    • O -bparâmetro especifica o uso da área de transferência em vez das seleções "primária" ou "secundária" de X.
  • <<<é uma sintaxe especial do Bash chamada "Here String".
    Basicamente, expande (não avalia!) O argumento (apenas um!) Depois dele e o redireciona como string para o stdin (entrada padrão) do comando antes / depois do qual está.

  • !!:qé chamado de "comando bang" para expansão do histórico no bash. Ele se substitui por qualquer linha de comando digitada anteriormente.
    Para obter mais informações, leia a página de manual local executando man history(a página de manual on-line não é útil).

    • A !!representa a linha de comando anterior e é um sinônimo para !-1.
      Obviamente !-2significa então a segunda última linha de comando. Não esqueça o sinal de menos -, caso contrário, ele retornará o 2º (3º / ...) comando que você já digitou.
    • Ele :qmodifica o comando bang e diz ao bash para incluir a substituição entre aspas simples ( ') para impedir uma expansão adicional pelo shell.

Variação de comando 2 (um pouco mais):

echo !!:q | xsel -ib
  • echo tem o trabalho simples de imprimir todos os seus argumentos no stdout do terminal.

  • !!:qé chamado de "comando bang" para expansão do histórico no bash. Ele se substitui por qualquer linha de comando digitada anteriormente.

    • A !!representa a linha de comando anterior e é um sinônimo para !-1. Obviamente !-2significa então a segunda última linha de comando. Não esqueça o sinal de menos -, caso contrário, ele retornará o 2º (3º / ...) comando que você já digitou.
    • Ele :qmodifica o comando bang e diz ao bash para incluir a substituição entre aspas simples ( ') para impedir uma expansão adicional pelo shell.
  • |é um cano. Ele redireciona a saída do terminal ("stdout") do comando antes para a entrada do terminal ("stdin") do comando após ele.

  • xselé uma ferramenta de linha de comando para acessar as pranchetas do X.
    Para obter mais informações, leia a página de manual onÍcone da página de manual - line ou executando man xsel.

    • O -iparâmetro diz xselpara ler a partir do stdin (geralmente isso significa entrada do teclado, mas vamos redirecionar algo aqui)
    • O -bparâmetro especifica o uso da área de transferência em vez das seleções "primária" ou "secundária" de X.

Variação de comando 3 (alias):

Um alias do bash é uma coisa interessante se você não quer se lembrar de comandos longos ou complicados que costuma usar. Você pode atribuir esse comando a um nome alternativo simples, que pode ser executado em vez do comando longo para obter o mesmo.

Infelizmente, como os comandos bang são um recurso especial do Bash e são expandidos antes que os alias sejam resolvidos, você não pode simplesmente alias uma das variações acima, porque a !!peça não funcionará. Há uma solução alternativa.

Para definir o alias, execute a seguinte linha no seu terminal. Observe que você pode escolher qualquer nome de variável Bash válido em vez de copylastcommand:

alias copylastcommand='history -p \!\! | xsel -ib'

No entanto, isso só é persistente na sua sessão atual do Bash, o que significa que o alias desaparecerá depois que você fechar a janela do terminal. Você pode torná-lo persistente em todas as suas sessões do Bash adicionando esta linha acima ao final do seu ~/.bashrcarquivo ou ao seu ~/.bash_aliasesarquivo, se você tiver uma.

Novamente, uma breve quebra de linha:

  • alias name='command'é a sintaxe para definir um alias no Bash. O commandserá executado sempre que você executar a namepartir de agora.

  • history -p \!\!envia a linha de comando executada anteriormente para stdout (saída padrão). Sem a -popção, ele não apenas imprimiria, mas também executaria o comando novamente.
    Observe que precisamos escapar do bangs ( !) com barras invertidas ( \), porque, caso contrário, o bash os expandiria quando tentamos definir o alias, o que não faz sentido, pois eles precisam estar no alias como estão.
    Novamente, você também pode especificar o [n] -ésimo comando recente substituindo o segundo retorno por -n, por exemplo \!-2.

  • |é um cano. Ele redireciona a saída padrão ("stdout") do comando antes dele para o padrão do terminal ("stdin") do comando após ele.

  • xselé uma ferramenta de linha de comando para acessar as pranchetas do X.
    Para obter mais informações, leia a página de manual onÍcone da página de manual - line ou executando man xsel.

    • O -iparâmetro diz xselpara ler a partir do stdin (geralmente isso significa entrada do teclado, mas vamos redirecionar algo aqui)
    • O -bparâmetro especifica o uso da área de transferência em vez das seleções "primária" ou "secundária" de X.
Byte Commander
fonte
11
Boa resposta, mas você poderia evitar o cachimbo? Bonita por favor? <<<"!!" xsel -ib
kos
@ kos sim, obrigado. Isso facilita um pouco. Você poderia ajudar minha mente a lembrar como a <<<estrutura é chamada novamente? E eu acho que <<<!!:q xsel -ibé melhor (deixar o comando bang histórico fazer a citação), ou você discorda?
Byte Commander
Mas !!:qusa aspas simples ( ') ...
Byte Commander
Você está certo, a expansão seria realizada usando <<<"!!" xsel -ib. Sim, <<<!!:q xsel -ibé melhor, vá em frente.
kos
Bom, xseltem uma sintaxe interessante
Sergiy Kolodyazhnyy
5

Você pode usar xclip:

some_command | xclip -selection c

Então, no seu caso:

youtube-dl .... | xclip -selection c

c significa área de transferência.

Pode ser necessário instalar xclipprimeiro:

sudo apt-get install xclip

EDITAR:

Se você deseja que o comando digitado (e não a saída) seja copiado para a área de transferência, você pode usar as seqüências de caracteres Here:

 xclip -selection c <<<"$(echo foobar)"

Ou um cachimbo:

echo foobar | xclip -selection c
heemail
fonte
11
Ainda recebo os comandos de saída, mas só quero a própria linha.
Valter Silva
echo "command" | xclip -selection clipboard... Ou torná-lo um roteiro sob~/.bin : echo "$@" | xclip -selection clipboard. Digamos que você o salve como "cpy", você poderá cpy youtube-dl stuffe ele será copiado para a área de transferência sem ser executado.
Alex1
E se você quer que ele seja executado ... echo "$@" | xclip -selection c && $@ou algo mais inteligente com eval ...
Alex
@ValterHenrique Por favor, verifique as minhas edições ..
heemayl
3

Acabei de fazer um pequeno script para zshque isso aconteça xclip:

#!/bin/zsh
export HISTFILE=~/.zsh_history
fc -R
fc -l | tail -n 2 | sed -n '1p' | sed 's/[0-9]*  //' | xclip -selection c

Este script copia o último comando que foi inserido no shell / terminal na área de transferência do sistema. Não funcionaria em um servidor remoto típico.

Eu pensei que levaria apenas alguns minutos para escrever esse script, mas levou surpreendentemente tempo para fazê-lo funcionar, enquanto eu tropecei no modo como zshlida com a história.

O tail -n 2primeiro sedé lidar com o fato de que o comando para esse script em si está sendo registrado no histórico e, portanto, obtém duas linhas do histórico e remove o último.

Esse script funciona, e foi um quebra-cabeça divertido, mas estou realmente curioso para saber se existe uma maneira mais simples ou mais elegante de fazer isso zsh.

alec
fonte
Bem, você provavelmente poderia simplificar os comandos taile sedem um ou dois comandos. Aqueles comandos uso !!que é explicado aqui - deve estar disponível em ZSH ....
Wilf
Ah, de !!fato parece que seria útil aqui, obrigado!
alec 25/05
0

Estou usando como gerente da área de transferência, então.

alias pbpaste='xclip -i -selection clipboard -o'
alias pbcopy='xclip -selection clipboard'
vimscratch='vim -c 'setlocal buftype=nofile bufhidden=wipe nobuflisted noswapfile' 

Último comando para a área de transferência

alias last2cb='fc -ln -1 | pbcopy'

Prancheta para vim scratch

alias vcb='pbpaste | vimscratch -'

Específico para ZSH

# Copy the most recent command to the clipboard
function _pbcopy_last_command(){
    fc -ln -1 | pbcopy
}
zle -N pbcopy-last-command _pbcopy_last_command
bindkey '^x^y' pbcopy-last-command
# Ctrl-x Ctrl-y  to copy last command to the clipboard


# Edit content of clipboard on vim (scratch buffer)
function _edit_clipboard(){
    pbpaste | vim -c 'setlocal buftype=nofile bufhidden=wipe nobuflisted noswapfile' -
}
zle -N edit-clipboard _edit_clipboard
bindkey '^x^v' edit-clipboard
# Ctrl-x Ctrl-v to edit clipboard on vim


# define function that retrieves and runs last command
function run-again {
    # get previous history item
    zle up-history
    # confirm command
    zle accept-line
}
# define run-again widget from function of the same name
zle -N run-again
bindkey '\er' run-again
# alt-r to run last command again

Eu acho que essas idéias podem ajudar você a criar sua própria solução

SergioAraujo
fonte