2009-03-25 4 views
17

ssh를 통해 몇 대의 라우터에 연결되는 expect 스크립트가 있습니다. 이 모든 라우터는 동일한 암호를 가지고 있습니다 (나는 잘못 알고 있습니다). 스크립트는 라우터에 연결할 수 있도록 암호를 알아야합니다. 현재 암호는 명령 줄에서 인수로 내 스크립트에 전달되지만 이는 실행중인 프로세스뿐만 아니라 .bash_history 파일에도 해당 암호의 흔적이 있음을 의미합니다. 그래서 대신 가능하면 자동으로 사용자에게 암호를 묻는 메시지를 표시합니다.암호를 묻는 메시지가 나타나게하려면 어떻게해야합니까?

예상대로 암호를 입력하라는 메시지를 표시 할 수 있는지 여부를 알고 계십니까?

감사합니다.

편집 : 라우터 대신 서버에 연결하는 경우 암호 대신 ssh 키를 사용할 것입니다. 하지만 내가 사용하고있는 라우터는 암호 만 지원합니다.

답변

28

사용이 기대는 stty 명령과 같이 : 그것은이 send_user를 호출하기 전에 stty -echo를 호출하는 것이 중요합니다

# grab the password 
stty -echo 
send_user -- "Password for [email protected]$host: " 
expect_user -re "(.*)\n" 
send_user "\n" 
stty echo 
set pass $expect_out(1,string) 

#... later 
send -- "$pass\r" 

하는 것으로 - 잘 모르겠어요 이유를 정확하게 : 나는 타이밍 문제 같아요.

프로그래머가 을 읽을 모든해야 기대하는 책 : 돈 리브 (Don Libe)에 의해 기대 탐색

+2

쿨 감사합니다! 이 언어가 얼마나 관대한지는 놀라워요. "set pass $ expect_out (1, string)"이라는 단어를 "string"이라는 단어 앞에 공백으로 썼다. 많은 문서를 찾을 수 없습니다. 기대 이상의 다른 해결책이 있었으면합니다. 어쨌든, 고마워. – MiniQuark

+0

"많은 문서를 찾을 수 없습니다"? 일반적으로 너무 잘 쓰여서 2 판이 필요하지 않은 것으로 간주되는 전체 책이 있습니다. 진지하게, 그 책을 확인해. –

+1

Re : "1"과 "string"사이의 공백 - Tcl (따라서 예상 됨)에는 다차원 배열이 없습니다. 배열 키는 단지 문자열이며 "1, string"과 "1, string"은 다릅니다. –

6

OK, 위의 두 답변을 병합 (또는 그들은 지금 아래 또는 어디든지!) :

#!/usr/local/bin/expect 
log_user 0 
set timeout 10 
set userid "XXXXX" 
set password "XXXXXX" 

# ############## Get two arguments - (1) Device (2) Command to be executed 
set device [lindex $argv 0] 
set command [lindex $argv 1] 

# grab the password 
stty -echo 
send_user -- "Password for [email protected]$host: " 
expect_user -re "(.*)\n" 
send_user "\n" 
stty echo 
set pass $expect_out(1,string) 

spawn /usr/local/bin/ssh -l $userid $device 
match_max [expr 32 * 1024] 

expect { 
    -re "RSA key fingerprint" {send "yes\r"} 
    timeout {puts "Host is known"} 
} 

expect { 
    -re "username: " {send "$userid\r"} 
    -re "(P|p)assword: " {send "$pass\r"} 
    -re "Warning:" {send "$pass\r"} 
    -re "Connection refused" {puts "Host error -> $expect_out(buffer)";exit} 
    -re "Connection closed" {puts "Host error -> $expect_out(buffer)";exit} 
    -re "no address.*" {puts "Host error -> $expect_out(buffer)";exit} 

    timeout {puts "Timeout error. Is device down or unreachable?? ssh_expect";exit} 
} 

expect { 
    -re "\[#>]$" {send "term len 0\r"} 
    timeout {puts "Error reading prompt -> $expect_out(buffer)";exit} 
} 


expect { 
    -re "\[#>]$" {send "$command\r"} 

    timeout {puts "Error reading prompt -> $expect_out(buffer)";exit} 
} 

expect -re "\[#>]$" 
set output $expect_out(buffer) 
send "exit\r" 
puts "$output\r\n" 

참고 다른 답과 일치하도록 $ password 변수를 $ pass로 변경했습니다.

0

또는 SSH_ASKPASS 환경 변수를 사용하여 X11을 통해 ssh에서 암호를 수집하도록 할 수 있습니다. 남자 페이지에서

:

> SSH_ASKPASS 
>  If ssh needs a passphrase, it will read the passphrase from the 
>  current terminal if it was run from a terminal. If ssh does not 
>  have a terminal associated with it but DISPLAY and SSH_ASKPASS 
>  are set, it will execute the program specified by SSH_ASKPASS 
>  and open an X11 window to read the passphrase. This is particularly 
>  useful when calling ssh from a .xsession or related script. 
>  (Note that on some machines it may be necessary to redirect the 
>  input from /dev/null to make this work.) 
관련 문제