Usar o 'expect' no programa bash para fornecer a senha ao comando SSH
para aqueles que querem responder que eu devo usar as chaves SSH por favor abstenham-se
estou a tentar usar o expect in an bash script para fornecer a senha SSH. Fornecer a senha funciona, mas eu não acabo na sessão SSH como deveria, vai de encontro ao bash.
o meu guião:
#!/bin/bash
read -s PWD
/usr/bin/expect <<EOD
spawn ssh -oStrictHostKeyChecking=no -oCheckHostIP=no usr@$myhost.example.com'
expect "password"
send "$PWD\n"
EOD
echo "you're out"
o resultado do meu programa:
spawn ssh -oStrictHostKeyChecking=no -oCheckHostIP=no usr@$myhost.example.com
usr@$myhost.example.com's password: you're out
Eu gostaria de ter a minha sessão SSH e só quando sair dela para voltar ao meu guião da bash.
A razão pela qual estou a usar o bash antes esperar é porque eu tenho um menu que eu posso escolher a unidade para se conectar.
Obrigado.
8 answers
#!/usr/bin/expect
eval spawn ssh -oStrictHostKeyChecking=no -oCheckHostIP=no usr@$myhost.example.com
#use correct prompt
set prompt ":|#|\\\$"
interact -o -nobuffer -re $prompt return
send "my_password\r"
interact -o -nobuffer -re $prompt return
send "my_command1\r"
interact -o -nobuffer -re $prompt return
send "my_command2\r"
interact
A solução de amostra para o bash pode ser:
#!/bin/bash
/usr/bin/expect -c 'expect "\n" { eval spawn ssh -oStrictHostKeyChecking=no -oCheckHostIP=no usr@$myhost.example.com; interact }'
Isto vai esperar pela sessão interactiva enter e than return (por um momento).
A maneira mais fácil é usar o sshpass . Isto está disponível nos repos Ubuntu / Debian e você não tem que lidar com a integração expect com bash.
Um exemplo:
sshpass -p<password> ssh <arguments>
sshpass -ptest1324 ssh [email protected] ls -l /tmp
O comando acima pode ser facilmente integrado com um script bash.
Nota: por favor, leia As considerações de Segurança secção em man sshpass
para uma compreensão completa das implicações de segurança.
Adicione o comando 'interact' expect imediatamente antes da sua EOD:
#!/bin/bash
read -s PWD
/usr/bin/expect <<EOD
spawn ssh -oStrictHostKeyChecking=no -oCheckHostIP=no usr@$myhost.example.com'
expect "password"
send "$PWD\n"
interact
EOD
echo "you're out"
Isto deve permitir-lhe interagir com a máquina remota até se desligar. Depois voltas para o bash.
Depois de procurar uma resposta para a pergunta durante meses, finalmente encontro uma solução realmente melhor: escrever um script simples.
#!/usr/bin/expect
set timeout 20
set cmd [lrange $argv 1 end]
set password [lindex $argv 0]
eval spawn $cmd
expect "assword:"
send "$password\r";
interact
Coloque em /usr/bin/exp
, então você pode usar:
exp <password> ssh <anything>
exp <password> scp <anysrc> <anydst>
Use a ferramenta auxiliar {[[0]} (do hxtools, não do pmt), ela funciona sem ter que esperar um prompt particular do programa ssh.
Certifique-se também de utilizar
send -- "$PWD\r"
Em vez disso, as senhas que começam com um traço (-) irão falhar de outra forma.
O texto acima não irá interpretar um texto a começar com um traço como uma opção para o comando send.
Um programa de espera simples
Remotelogin.Val
#!/usr/bin/expect
set user [lindex $argv 1]
set ip [lindex $argv 0]
set password [lindex $argv 2]
spawn ssh $user@$ip
expect "password"
send "$password\r"
interact
Exemplo:
./Remotelogin.exp <ip> <user name> <password>
Outra maneira que achei útil para usar um pequeno esperar um script de um script bash é a seguinte.
...
bash-script start
bash-commands
...
expect - <<EOF
spawn your-command-here
expect "some-pattern"
send "some-command"
...
...
EOF
...
more bash commands
...
Isto funciona porque ...If the string "-" is supplied as a filename, standard input is read instead...