Passa o flag de background (&) através de expect e ssh

3

Minha linha de comando / bash fu é extremamente fraca, mas estou tentando aprimorar minhas habilidades. Espero que alguém possa ajudar.

Eu escrevi um script super simples de expect para que eu possa usar o SSH em uma caixa sem cabeça que estou usando no trabalho, além de enviar a senha (por motivos que não posso expandir, não podemos use chaves públicas para automatizar o login). O script:

#!/usr/bin/expect -f
set timeout 30
spawn ssh -X ***@10.101.0.133 $argv
match_max 100000
expect "*?assword:*"
send -- "***\r"
interact

A caixa tem um ambiente de desenvolvedor e o Eclipse instalado; Na maior parte do tempo em que estou me conectando a ele, terminarei tunelando direto no Eclipse para trabalhar em algum código que mantemos nessa caixa, então geralmente acabo usando script eclipse .

Como posso passar o sinal & para esperar para que ele veja o E comercial como um argumento para a sessão ssh que estou gerando? Quando eu uso script eclipse & apenas script de backgrounds na minha máquina em vez de fazer algo na máquina remota, mas eu gostaria de ser capaz de enviar o & para script para que quando o Eclipse é iniciado na caixa remota Eu ainda posso usar o shell da caixa.

Esta é provavelmente uma pergunta incrivelmente boba, mas qualquer ajuda seria muito apreciada.

Atualização: Eu descobri que escapei do e comercial (que definitivamente era um momento "no duh" para mim ... meh). Mas isso leva a um novo problema. Parece que quando eu passo qualquer argumento ao meu script, o comando esperar nunca me permite interagir; uma vez que o comando passado executa a sessão SSH termina. Eu estou supondo que isso não é uma limitação de esperar, mas uma parte do comportamento do ssh. Obrigado pelas suas respostas.

Atualização 2: Apenas por uma questão de posteridade, obtive o comportamento desejado, modificando o script para ficar assim:

#!/usr/bin/expect -f
set timeout 30
spawn ssh -X ***@10.101.0.133
match_max 100000
expect "*?assword:*"
send -- "***\r"
send $argv
send -- "\r"
interact
    
por Doug Stephen 29.06.2011 / 20:56

3 respostas

3

Geekosaur está certo em apontar que você pode passar a Ampersand citando , (você também pode escapar com script eclipse \& ), mas há algo mais que podemos sugerir uma maneira melhor de fazer aqui. Parece que você escreveu um script de espera para ssh em outra máquina com sua senha e executa um comando.

Você deve saber que tanto do ponto de vista prático como do ponto de vista de segurança, essa não é uma solução muito boa. Praticamente, toda a situação é frágil e várias situações em potencial podem fazer com que ela se quebre, e a depuração é confusa no futuro. Do ponto de vista da segurança, é louco porque a senha do seu sistema em outra máquina é salva em um arquivo de texto em algum lugar!

Existe uma maneira melhor! A autenticação baseada em chave foi criada para resolver esse problema. Você cria pares de chaves - uma parte vai no servidor em um no cliente - que podem autenticar sem uma senha. Isso permite que você execute o ssh a partir de scripts sem usar o comando AND sem salvar sua senha em nenhum lugar. Como uma etapa extra, você pode até mesmo criptografar a chave local com uma frase secreta e usar um agente ou gerenciador de chaves para carregar a chave em um shell antes de executar qualquer script que precise usá-la.

Edit: Senti falta que você disse que não pode usar a autenticação de chave pública. Isso é conversa louca. Estou deixando minha resposta para o benefício de quaisquer leitores que também possam ter perdido a exigência e não percebam que seu script é um hack:)

    
por 29.06.2011 / 21:35
4

Se você não precisasse digitar a senha, poderia fazer

ssh -t 'eclipse & exec bash'

O sinalizador -t informa ao ssh para alocar um terminal, mesmo que você esteja fornecendo um nome de comando. O shell remoto deve ser não interativo porque está executando um comando, mas a última coisa que faz é exec bash , ou seja, substitua-se por uma nova instância de shell, que é interativa. (Substitua bash por zsh ou qualquer que seja seu shell favorito.)

Se você precisar digitar uma senha, você precisa digitá-la em um terminal de algum tipo (e é por isso que você precisa de expect se você for automatizar essa parte). ssh deliberadamente se recusa a ler as senhas de um argumento ou arquivo de linha de comando.

Uma coisa que pode ser útil é criar uma conexão SSH principal de uma vez por todas, o piggyback nele. Enquanto o mestre estiver em execução, você pode estabelecer conexões escravas que não exigem autenticação. Coloque as seguintes linhas em seu ~/.ssh/config :

Host nickname
HostName 10.101.0.133
ControlPath=~/.ssh-control:%l:%p:%r

Crie a conexão principal com ssh -MX nickname eclipse (dentro de expect , se você ainda quiser passar a senha automaticamente). Então, enquanto o Eclipse estiver em execução, você poderá fazer ssh nickname sem fazer nova autenticação.

    
por 29.06.2011 / 22:39
2

Use aspas: script 'eclipse &' . (Observe que você não cita $argv no script expect ; Tcl segue regras diferentes de sh .)

    
por 29.06.2011 / 20:59