Como enviar dados para a área de transferência local a partir de uma sessão SSH remota

161

Pergunta do Borderline ServerFault, mas estou programando alguns scripts de shell, então estou tentando aqui primeiro :)

A maioria dos * nixes possui um comando que permite direcionar / redirecionar a saída para a área de transferência / área de transferência local e recuperar a partir da mesma. No OS X, esses comandos são

pbcopy, pbpaste 

Existe alguma maneira de replicar essa funcionalidade enquanto o SSHed está em outro servidor? Isso é,

  1. Estou usando o computador A.
  2. Abro uma janela do terminal
  3. Eu SSH para Computador B
  4. Eu executo um comando no Computador B
  5. A saída do Computador B é redirecionada ou copiada automaticamente para a área de transferência do Computador A.

E sim, eu sei que eu poderia (estremecer) usar o mouse para selecionar o texto do comando, mas me acostumei tanto ao fluxo de trabalho que envia a saída diretamente para a área de transferência que quero o mesmo para minhas sessões remotas.

O código é útil, mas abordagens gerais também são apreciadas.

Alan Storm
fonte

Respostas:

89

Estou ressuscitando esse segmento porque tenho procurado o mesmo tipo de solução e encontrei um que funcione para mim. É uma pequena modificação de uma sugestão do OSX Daily .

No meu caso, eu uso o Terminal na minha máquina OSX local para conectar-me a um servidor Linux via SSH. Como o OP, eu queria poder transferir pequenos pedaços de texto do terminal para a minha área de transferência local, usando apenas o teclado.

A essência da solução:

commandThatMakesOutput | ssh desktop pbcopy

Quando executado em uma sessão ssh em um computador remoto, esse comando pega a saída do commandThatMakesOutput (por exemplo, ls, pwd) e canaliza a saída para a área de transferência do computador local (o nome ou o IP da "área de trabalho"). Em outras palavras, ele usa ssh aninhado: você está conectado ao computador remoto por meio de uma sessão ssh, executa o comando e o computador remoto se conecta à área de trabalho por meio de uma sessão ssh diferente e coloca o texto na área de transferência.

Requer que sua área de trabalho seja configurada como um servidor ssh (que deixo para você e o google). É muito mais fácil se você configurou chaves ssh para facilitar o uso rápido de ssh, de preferência usando uma senha por sessão ou o que suas necessidades de segurança exigirem.

Outros exemplos:

ls  | ssh desktopIpAddress pbcopy
pwd |  ssh desktopIpAddress pbcopy

Por conveniência, criei um arquivo bash para reduzir o texto necessário após o canal:

#!/bin/bash
ssh desktop pbcopy

No meu caso, estou usando uma chave especialmente nomeada

Salvei-o com o nome de arquivo cb (my mnemonic (ClipBoard). Coloque o script em algum lugar do seu caminho, torne-o executável e pronto:

ls | cb
rhileighalmgren
fonte
3
Costumo fazer isso no vim. Para fazer isso, selecione o que você deseja copiar no modo visual, em seguida, digite::'<,'>w !ssh desktop pbcopy
Mike Brennan
@MikeBrennan Quando você seleciona o texto, por que não pressiona cmd + C (ou qualquer tecla de cópia que você definiu)? ...
Petr Peller
36
Assim, ele realmente funciona quando a área de trabalho tem um IP estático e é acessível a partir da caixa em que você inseriu o SSH. Esse nunca é o meu caso.
kqw
6
Não seria o contrário? ssh user @ remote 'commandThatMakesOutput' | pbcopy
rulio 4/14/14
Eu precisava da -e nonebandeira ssh descrita aqui: unix.stackexchange.com/questions/210615/...
Pat Myron
122

Minha maneira favorita é ssh [remote-machine] "cat log.txt" | xclip -selection c. Isso é mais útil quando você não deseja (ou não pode) ssh de remoto para local.

Edit: em Cygwin ssh [remote-machine] "cat log.txt" > /dev/clipboard.

Edit: Um comentário útil de nbren12:

Quase sempre é possível configurar uma conexão ssh reversa usando o encaminhamento de porta SSH. Basta adicionar RemoteForward 127.0.0.1:2222 127.0.0.1:22à entrada do servidor no seu local .ssh/confige, em seguida, executar ssh -p 2222 127.0.0.1na máquina remota, que redirecionará a conexão para a máquina local. - nbren12

Dominykas Mostauskis
fonte
6
+1: muito mais fácil do que outras soluções quando uma conexão SSH reversa não é possível!
precisa saber é o seguinte
9
Você merece mais curtidas por essa solução extremamente simples!
Kamil Dziedzic
31
Para aqueles de nós no Mac OSX,ssh [remote-machine] "cat log.txt" | pbcopy
chowey
1
De acordo com este relatório aqui , eu tive que usar catpara fazer isso funcionar no cygwin Windows 8: ssh [remote-machine] "cat log.txt" | cat > /dev/clipboard(é claro, meu comando remoto não era cat; era algo mais dentro de uma máquina virtual vagante, então eu realmente corri vagrant ssh -c "command" | cat > /dev/clipboard)
tiby
7
É quase sempre possível configurar uma conexão ssh reversa usando o encaminhamento de porta SSH. Basta adicionar RemoteForward 127.0.0.1:2222 127.0.0.1:22à entrada de servidores no seu local .ssh/confige executar ssh -p 2222 127.0.0.1na máquina remota, que redirecionará a conexão para a máquina local.
Nbren12
30

Encontrei uma ótima solução que não requer uma conexão ssh reversa!

Você pode usar o xclip no host remoto, juntamente com o encaminhamento ssh X11 e o XQuartz no sistema OSX.

Para configurar isso:

  1. Instale o XQuartz (fiz isso com a receita soloist + pivotal_workstation :: xquartz , mas você não precisa)
  2. Execute o XQuartz.app
  3. Abra as Preferências do XQuartz ( kb_command+ ,)
  4. Verifique se a opção "Ativar sincronização" e "Atualizar a área de transferência quando a área de transferência é alterada" estão marcadas Exemplo da janela Preferências do XQuartz
  5. ssh -X remote-host "echo 'hello from remote-host' | xclip -selection clipboard"
TrinitronX
fonte
1
Como isso é diferente ssh remote-host "echo 'hello from remote-host' | pbcopy? Esta seria uma excelente resposta se ele iria trabalhar algo como isto: ssh -X remote-hostem seguida, no host remoto:echo 'hello from remote-host' | xclip -selection clipboard
kqw
5
@KasperSouren. Eu acredito que funciona como você está esperando. O `| xclip` está entre aspas duplas.
Gdw2
1
Em 2016, essa é obviamente a melhor solução sem problemas. Esqueça outras soluções baseadas em reverse-ssh.
shivams
1
Existe uma maneira de fazer isso sem ser apenas um comando único? Quero fazer login no meu servidor remoto em uma sessão interativa pelo ssh e poder enviar para a área de transferência local arbitrariamente. Isso requer ssh reverso?
Kvass
2
@Kvass: Enquanto você estiver usando o -XX11 Forwarding over SSH, os programas X11 poderão atualizar sua área de transferência através das configurações do XQuartz acima. O comando único é demonstrar que o envio de algo echopara a área de transferência do host remoto xclipfunciona e deve ser sincronizado com o host do cliente SSH local. Observe como @ gdw2 diz: "O texto | xclipestá entre aspas duplas". Como tal, ele será executado como um comando no servidor remoto para enviar algo para a área de transferência.
TrinitronX
18

Porta de túnel reverso no servidor ssh

Todas as soluções existentes precisam:

  • X11 no cliente (se houver, xclipno servidor funciona muito bem) ou
  • o cliente e o servidor estejam na mesma rede (o que não acontece se você estiver trabalhando tentando acessar o computador doméstico).

Aqui está outra maneira de fazer isso, embora seja necessário modificar a forma como você ssh no seu computador.

Eu comecei a usar isso e não é nem de longe tão intimidador quanto parece, então tente.

Cliente (inicialização da sessão ssh)

ssh username@server.com -R 2000:localhost:2000

(dica: torne isso uma combinação de teclas para que você não precise digitá-lo)

Cliente (outra guia)

nc -l 2000 | pbcopy

Nota: se você não tiver pbcopy, basta teeenviá-lo para um arquivo.

Servidor (dentro da sessão SSH)

cat some_useful_content.txt | nc localhost 2000

Outras notas

Na verdade, mesmo se você estiver no meio de uma sessão ssh, há uma maneira de iniciar um túnel, mas eu não quero assustar as pessoas do que realmente não é tão ruim quanto parece. Mas adicionarei os detalhes mais tarde, se houver algum interesse

Sridhar Sarnobat
fonte
1
+1 - isso é muito legal. No entanto - o cat some_useful_content.txt | nc localhost 2000comando parece travar quando faço isso. Eu preciso manualmente CTR-c para pará-lo, e é só então que o conteúdo fica ao meu clipe cliente / papelão
Alan Storm
1
Esperará até que alguém desenfileire os dados na outra extremidade.
Sridhar Sarnobat
Na verdade, acho que não entendi sua pergunta. Não sei por que isso acontece.
Sridhar Sarnobat
nc -l -pfunciona para mim, mas simplesmente nc -lnão. E também tenho o problema do @AlanStorm.
HappyFace 16/09
1
Resolvi o problema de pendurar o netcat especificando -c. Eu uso o GNU netcat instalado pelo brew.
HappyFace 16/09
7

Existem várias ferramentas para acessar as seleções do X11, incluindo xclip e XSel . Observe que o X11 tradicionalmente possui várias seleções e a maioria dos programas tem algum entendimento da área de transferência e da seleção primária (que não são iguais). O Emacs também pode trabalhar com a seleção secundária, mas isso é raro, e ninguém realmente sabe o que fazer com os buffers de corte ...

$ xclip -help
Uso: xclip [OPTION] [FILE] ...
Acesse uma seleção de servidor X para leitura ou gravação.

  -i, -in lê texto na seleção X a partir de arquivos ou entradas padrão
                   (padrão)
  -o, -out imprime a seleção para saída padrão (geralmente para
                   canalização para um arquivo ou programa)
  -l, -loops número de pedidos de seleção a aguardar antes de sair
  -d, -display do X ao qual se conectar (por exemplo, localhost: 0 ")
  informações de uso -h, -help
      seleção de seleção a acessar ("primário", "secundário", "área de transferência" ou "corte de buffer")
      -noutf8 não trata texto como utf-8, use unicode antigo
      informações da versão
      somente erros silenciosos, executados em segundo plano (padrão)
      tranquilo em primeiro plano, mostre o que está acontecendo
      -verbose comentário em execução

Relatar erros para <[email protected]>
$ xsel -help
Uso: xsel [opções]
Manipule a seleção X.

Por padrão, a seleção atual é emitida e não modificada se ambos
entrada e saída padrão são terminais (ttys). De outra forma,
a seleção atual é emitida se a saída padrão não for um terminal
(tty) e a seleção é definida na entrada padrão se a entrada padrão
não é um terminal (tty). Se alguma opção de entrada ou saída for fornecida,
o programa se comporta apenas no modo solicitado.

Se entrada e saída forem necessárias, a seleção anterior será
saída antes de ser substituído pelo conteúdo da entrada padrão.

Opções de entrada
  -a, --append Adiciona entrada padrão à seleção
  -f, --follow Anexa à seleção à medida que a entrada padrão cresce
  -i, --input Leia a entrada padrão na seleção

Opções de saída
  -o, --output Grava a seleção na saída padrão

Opções de ação
  -c, --clear Limpar a seleção
  -d, --delete Solicita que a seleção seja limpa e que
                        o aplicativo que o possui exclui seu conteúdo

Opções de seleção
  -p, --primary Opera na seleção PRIMARY (padrão)
  -s, --secundary Opera na seleção SECUNDARY
  -b, --clipboard Opere na seleção CLIPBOARD

  -k, --keep Não modifique as seleções, mas faça o comando PRIMARY
                        e seleções SECUNDÁRIAS persistem mesmo após o
                        programas que foram selecionados na saída.
  -x, --exchange Troque as seleções PRIMARY e SECONDARY

X opções
  --display displayname
                        Especifique a conexão com o servidor X
  -t ms, --selectionTimeout ms
                        Especifique o tempo limite em milissegundos dentro do qual o
                        a seleção deve ser recuperada. Um valor de 0 (zero)
                        especifica sem tempo limite (padrão)

Opções diversas
  -l, --logfile Especifique o arquivo para o qual registrar erros quando desanexado.
  -n, --nodetach Não desconecte do terminal de controle. Sem
                        Nesta opção, o xsel bifurcará para se tornar um plano de fundo
                        processo nos modos de entrada, troca e manutenção.

  -h, --help Exiba esta ajuda e saia
  -v, --verbose Imprime mensagens informativas
  --version Saída informações de versão e saída

Por favor, reporte os erros para <[email protected]>.

Em resumo, você deve tentar xclip -i/ xclip -oou xclip -i -sel clip/ xclip -o -sel clipou xsel -i/ xsel -oou xsel -i -b/ xsel -o -b, dependendo do que deseja.

efémero
fonte
4
Para adicionar @ephemient 's post: Para uso xclip & XSEL com um host remoto, você pode usar X11 Forwarding assim: ssh -C -X user@remote-host. Se a execução do xclip no lado remoto não estiver funcionando, verifique se X11Forwarding yesestá configurada no /etc/ssh/sshd_configarquivo remoto . Verifique também se xauthestá instalado no lado remoto. Para uma máquina sem cabeça, você pode instalar xauthe xvfb.
TrinitronX
Aqui está uma descrição com detalhes extras, além de ligações de teclas do vim.
precisa
1
@TrinitronX oh uau - batendo minha cabeça contra uma parede, obrigado pela xvfbmenção. Eu estava executando um servidor sem cabeça, portanto o X11 não deve estar sendo executado!
Cam
5

Esta é a minha solução baseada no túnel reverso SSH, netcat e xclip.

Primeiro, crie um script (por exemplo, clipboard-daemon.sh) em sua estação de trabalho:

#!/bin/bash
HOST=127.0.0.1
PORT=3333

NUM=`netstat -tlpn 2>/dev/null | grep -c " ${HOST}:${PORT} "`
if [ $NUM -gt 0 ]; then
    exit
fi

while [ true ]; do
    nc -l ${HOST} ${PORT} | xclip -selection clipboard
done

e inicie-o em segundo plano.

./clipboard-daemon.sh&

Ele iniciará a saída da tubulação nc para o processo xclip e respawning após receber parte dos dados

Em seguida, inicie a conexão ssh com o host remoto:

ssh user@host -R127.0.0.1:3333:127.0.0.1:3333

Enquanto estiver conectado na caixa remota, tente o seguinte:

echo "this is test" >/dev/tcp/127.0.0.1/3333

tente colar na sua estação de trabalho

É claro que você pode escrever um script de wrapper que inicie primeiro o clipboard-daemon.sh e depois a sessão ssh. É assim que funciona para mim. Aproveitar.

Krzysztof Księżyk
fonte
Essa solução é a que funcionou melhor para mim. não é muito complicado e funciona corretamente.
Marcel Valdez Orozco
Melhor solução na minha opinião. Você não precisa se preocupar em permitir a conexão ssh reversa, que tem implicações de segurança, e o loop infinito é um toque agradável.
R. Taukulis 14/02
4

Não é uma linha, mas não requer ssh extra .

  • instale netcatse necessário
  • usar termbin : cat ~/some_file.txt | nc termbin.com 9999. Isso copiará a saída para o termbinsite e imprimirá o URL na sua saída.
  • visite esse URL do seu computador, você obtém sua saída

Obviamente, não o use para conteúdo sensível.

maxbellec
fonte
Uau, isso é uma solução muito criativa.
Sridhar Sarnobat 12/10
3

Essa resposta se desenvolve tanto na resposta escolhida , adicionando mais segurança.

Essa resposta discutiu a forma geral

<command that makes output> | \
    ssh <user A>@<host A> <command that maps stdin to clipboard>

Onde a segurança pode faltar está nas sshpermissões permitindo <user B>sobre host B>a sshem host Ae executar qualquer comando.

É claro Bque o Aacesso já pode ser bloqueado por uma sshchave e pode até ter uma senha. Mas outra camada de segurança pode restringir o escopo de comandos permitidos que Bpodem ser executados A, por exemplo, para que rm -rf /não possam ser chamados. (Isso é especialmente importante quando a sshchave não possui uma senha.)

Felizmente, sshpossui um recurso interno chamado restrição de comando ou comando forçado . Veja ssh.com , ou esta questão serverfault.com .

A solução abaixo mostra a solução geral do formulário junto com a ssh restrição de comando imposta.

Exemplo de solução com restrição de comando adicionada

Esta solução aprimorada de segurança segue a forma geral - a chamada da sshsessão host-Bé simplesmente:

cat <file> | ssh <user-A>@<host A> to_clipboard

O restante mostra a configuração para que isso funcione.

Configuração da restrição de comando ssh

Suponha que a conta do usuário Bseja user-B, e B tenha uma chave ssh id-clip, criada da maneira usual ( ssh-keygen).

Então no user-Adiretório ssh existe um arquivo

/home/user-A/.ssh/authorized_keys

que reconhece a chave id-clipe permite a sshconexão.

Normalmente, o conteúdo de cada linha authorized_keysé exatamente a chave pública que está sendo autorizada, por exemplo, o conteúdo de id-clip.pub.

No entanto, para impor restrições de comando, o conteúdo da chave pública é anexado (na mesma linha) pelo comando a ser executado.
No nosso caso:

command="/home/user-A/.ssh/allowed-commands.sh id-clip",no-agent-forwarding,no-port-forwarding,no-user-rc,no-x11-forwarding,no-pty <content of file id-clip.pub>

O comando designado "/home/user-A/.ssh/allowed-commands.sh id-clip", e somente esse comando designado, é executado sempre que a chave id-clipé usada para iniciar uma sshconexão host-A- independentemente do comando que está escrito na sshlinha de comando .

O comando indica um arquivo de script allowed-commands.she o conteúdo desse arquivo de script é

#/bin/bash
#
# You can have only one forced command in ~/.ssh/authorized_keys. Use this
# wrapper to allow several commands.

Id=${1}

case "$SSH_ORIGINAL_COMMAND" in
    "to-clipboard")
          notify-send "ssh to-clipboard, from ${Id}"
        cat | xsel --display :0 -i -b
          ;;
    *)
        echo "Access denied"
        exit 1
        ;;
esac

A chamada original para ssha máquina Bfoi

... | ssh <user-A>@<host A> to_clipboard

A sequência to-clipboardé passada allowed-commands.shpela variável de ambiente SSH_ORIGINAL_COMMAND. Além disso, passamos o nome da chave id-clip, da linha na authorized_keysqual é acessada apenas por id-clip.

A linha

          notify-send "ssh to-clipboard, from ${Id}"

é apenas uma caixa de mensagens pop-up para informar que a área de transferência está sendo gravada - provavelmente também é um bom recurso de segurança. ( notify-sendfunciona no Ubuntu 18.04, talvez não outros).

Na linha

cat | xsel --display :0 -i -b

o parâmetro --display :0é necessário porque o processo não possui sua própria exibição X com uma área de transferência; portanto, ele deve ser especificado explicitamente. Esse valor :0funciona no Ubuntu 18.04 com o servidor de janelas Wayland. Em outras configurações, pode não funcionar. Para um servidor X padrão, esta resposta pode ajudar.

host-A /etc/ssh/sshd_config parâmetros

Finalmente, alguns parâmetros no /etc/ssh/sshd_confighost Aque devem ser configurados para garantir a permissão para conexão e permissão para usar ssh-key apenas sem senha:

PubkeyAuthentication yes
PasswordAuthentication no
ChallengeResponseAuthentication no
AllowUsers user-A

Para fazer o sshdservidor reler a configuração

sudo systemctl restart sshd.service

ou

sudo service sshd.service restart

conclusão

É um esforço para configurá-lo, mas outras funções além disso to-clipboardpodem ser construídas em paralelo na mesma estrutura.

Craig Hicks
fonte
1
O Xsel com encaminhamento remoto foi a única resposta que funcionou para mim no Ubuntu 18.04 executando o i3 localmente. Não é necessário encaminhamento X11.
Jay Stanley
2

A solução mais simples de todas, se você estiver no OS X usando o Terminal e estiver navegando em um servidor remoto e desejar obter os resultados de um arquivo de texto, log ou csv, simplesmente:

1) Cmd-Kpara limpar a saída do terminal

2) cat <filename>para exibir o conteúdo do arquivo

3) Cmd-Spara salvar a saída do terminal

Você removerá manualmente a primeira e a última linha do arquivo, mas esse método é um pouco mais simples do que depender de outros pacotes a serem instalados, "túneis reversos" e tentar ter um IP estático etc.

tw0000
fonte
+1 para uma técnica útil que eu me usei, mas isso obriga a perder o histórico do terminal e (como mencionado) o problema da primeira / última linha é um pouco complicado.
17553 Alan Storm
Acordou @AlanStorm
tw0000 17/07/2018
O problema mais significativo com essa abordagem é que ela salvará apenas o número de linhas que o buffer do terminal retém. Muitas vezes isso não é um problema, mas se você está tentando pegar o conteúdo de um arquivo de log, então você pode ficar sem capacidade,
Sridhar Sarnobat
Isso é verdade @ Sridhar-Sarnobat, não é uma solução muito boa em geral. Eu apenas uso scp!
Tw0000 #