Próbuję użyć Expect w skrypcie Bash, aby podać hasło SSH. Podanie hasła działa, ale nie kończę sesji SSH tak, jak powinienem. Wraca cieśniną do Basha.
Mój skrypt:
#!/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"
Wynik mojego skryptu:
spawn ssh -oStrictHostKeyChecking=no -oCheckHostIP=no usr@$myhost.example.com
usr@$myhost.example.com's password: you're out
Chciałbym mieć sesję SSH i dopiero po jej zakończeniu wrócić do mojego skryptu Bash.
Powodem, dla którego używam Bash przed Expect, jest to, że muszę używać menu. Mogę wybrać, z którym urządzeniem / urządzeniem się połączyć.
Tym, którzy chcą odpowiedzieć, że powinienem używać kluczy SSH, wstrzymajcie się.
Odpowiedzi:
Mieszanie Bash i Expect nie jest dobrym sposobem na osiągnięcie zamierzonego efektu. Spróbowałbym użyć tylko Oczekuj:
#!/usr/bin/expect eval spawn ssh -oStrictHostKeyChecking=no -oCheckHostIP=no usr@$myhost.example.com # Use the 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
Przykładowe rozwiązanie dla basha to:
#!/bin/bash /usr/bin/expect -c 'expect "\n" { eval spawn ssh -oStrictHostKeyChecking=no -oCheckHostIP=no usr@$myhost.example.com; interact }'
To zaczeka na Entersesję interaktywną, a następnie powróci (na chwilę).
źródło
Najłatwiej jest użyć sshpass . Jest to dostępne w repozytoriach Ubuntu / Debian i nie musisz zajmować się integracją z Bash.
Przykład:
Powyższe polecenie można łatwo zintegrować ze skryptem Bash.
Uwaga: zapoznaj się z sekcją „ Uwagi dotyczące bezpieczeństwa ”,
man sshpass
aby w pełni zrozumieć wpływ na bezpieczeństwo.źródło
sshpass
, że to zrobi, ale nawet wtedy jest okres, w którym nadal się uruchamia, zanim będzie w stanie to zrobić, gdy hasło jest dostępne dla każdego / każdego procesu.sshpass
jest używany w scenariuszu, w którym masz proste skrypty testowe, które są wykonywane w środowisku sieci lokalnej, w którym bezpieczeństwo nie jest głównym problemem. W rzeczywistości jest sekcja, wman sshpass
której wyjaśniono całą sekcję dotyczącą zagadnień bezpieczeństwa. Dodano to, aby odpowiedzieć, dzięki.Dodaj polecenie „interakcja” Oczekuj tuż przed 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"
Powinno to umożliwić interakcję ze zdalną maszyną do czasu wylogowania. Wtedy wrócisz do Bash.
źródło
expect eof
rozwiązała problem.'
zusr@$myhost.example.com'
i powinno działać. A może trzeba wymienić\n
z\r
, ale YMMVPo miesiącach szukania odpowiedzi na to pytanie w końcu znajduję naprawdę najlepsze rozwiązanie: napisanie prostego scenariusza.
#!/usr/bin/expect set timeout 20 set cmd [lrange $argv 1 end] set password [lindex $argv 0] eval spawn $cmd expect "Password:" send "$password\r"; interact
Umieść to
/usr/bin/exp
, a następnie możesz użyć:exp <password> ssh <anything>
exp <password> scp <anysrc> <anydst>
Gotowe!
źródło
expect "assword:"
pan na myśliexpect "password:"
?"assword"
dopasuje zarównoPassword
ipassword
.Upewnij się również, że używasz
send -- "$PWD\r"
zamiast tego hasła zaczynające się od myślnika (-) zawiodą w przeciwnym razie.
Powyższe nie zinterpretuje ciągu zaczynającego się od myślnika jako opcji polecenia wysyłania.
źródło
Prosty skrypt Expect:
Plik Remotelogin.exp
#!/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
Przykład:
źródło
Użyj narzędzia pomocniczego
fd0ssh
(z hxtools, a nie pmt). Działa bez konieczności oczekiwania konkretnego monitu odssh
programu.źródło
echo "yoursshpass" | fd0ssh ssh -c -L$port:$ip:$remote_port [email protected] &
DZIĘKI!sshpass
.Innym sposobem, który uznałem za przydatny w użyciu małego skryptu Expect ze skryptu Bash, jest następujący.
To działa, ponieważ
...If the string "-" is supplied as a filename, standard input is read instead...
źródło
-
tutaj, ponieważexpect
czytastdin
go domyślnie, jeśli wywołasz go bez argumentów. Jest to jednak przydatne, jeśli chcesz uruchomić go interaktywnie bez wiersza poleceń (expect
vs.expect -
) lub w przypadku, gdy robisz coś takiego, wexpect -f "$@"
którym pierwszym argumentem powinien być plik, nawet jeśli wygląda jak opcja (zaczyna się od-
). W takim przypadku, jeśli$1
(podany plik)-
to czyta zstdin
.sshpass
jest zepsuty, jeśli spróbujesz użyć go wewnątrz celu kompilacji Sublime Text , wewnątrz pliku Makefile. Zamiast tegosshpass
możesz użyćpassh
: https://github.com/clarkwang/passhZ
sshpass
tobą zrobiłbyś:sshpass -p pa$$word ssh user@host
Z
passh
tobą zrobiłbyś:passh -p pa$$word ssh user@host
Uwaga: nie zapomnij użyć
-o StrictHostKeyChecking=no
. W przeciwnym razie połączenie zawiesi się przy pierwszym użyciu. Na przykład:passh -p pa$$word ssh -o StrictHostKeyChecking=no user@host
Bibliografia:
źródło