2009-03-25 32 views
17

Tôi có một kịch bản mong đợi kết nối với một vài bộ định tuyến thông qua ssh. Tất cả các bộ định tuyến này đều có cùng một mật khẩu (tôi biết, nó sai) và kịch bản lệnh cần biết mật khẩu đó để có thể kết nối với các bộ định tuyến. Hiện tại, mật khẩu được chuyển cho kịch bản của tôi như một đối số trên dòng lệnh, nhưng điều này có nghĩa là có một dấu vết của mật khẩu đó trong tệp .bash_history của tôi cũng như trong các tiến trình đang chạy. Vì vậy, thay vào đó tôi muốn người dùng được nhắc nhập mật khẩu, nếu có thể âm thầm.Tôi làm cách nào để tạo một lời nhắc tập lệnh mong đợi cho mật khẩu?

Bạn có biết có thể nhắc người dùng nhập mật khẩu không?

Cảm ơn bạn.

Chỉnh sửa: nếu tôi kết nối với máy chủ thay vì bộ định tuyến, tôi có thể sử dụng khóa ssh thay vì mật khẩu. Nhưng các bộ định tuyến tôi đang sử dụng chỉ hỗ trợ mật khẩu.

Trả lời

28

Sử dụng mong đợi là stty lệnh như thế này:

# 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" 

Lưu ý rằng điều quan trọng là bạn phải gọi stty -echotrước gọi send_user - Tôi không chắc chắn chính xác lý do tại sao: Tôi nghĩ rằng đó là một vấn đề thời gian.

mong đợi tất cả các lập trình viên nên đọc các cuốn sách: Khám phá Expect bởi Don Libes

+2

mát cảm ơn! Thật tuyệt vời khi ngôn ngữ này không dung nạp như thế nào: Tôi đã viết "set pass $ expect_out (1, string)", với khoảng trắng trước từ "string", và nó bom. Tôi cũng không thể tìm thấy nhiều tài liệu. Tôi ước có một số giải pháp khác ngoài mong đợi. Dù sao, cảm ơn rất nhiều. – MiniQuark

+0

"không thể tìm thấy nhiều tài liệu"?!? Có một cuốn sách toàn bộ, thường được coi là rất tốt bằng văn bản rằng nó đã không cần một ấn bản thứ hai. Nghiêm túc, kiểm tra cuốn sách đó. –

+1

Re: một không gian giữa "1", và "chuỗi" - Tcl (và do đó mong đợi) không có mảng đa chiều. Khóa mảng chỉ là một chuỗi và "1, chuỗi" và "1, chuỗi" là khác nhau. –

6

OK, sáp nhập 2 câu trả lời ở trên (hoặc thấp hơn hoặc bất cứ nơi nào họ đang!):

#!/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" 

Lưu ý rằng Tôi đã thay đổi biến $ password thành $ pass để phù hợp với câu trả lời khác.

0

Hoặc bạn có thể cho phép ssh thu thập mật khẩu qua X11 bằng biến môi trường SSH_ASKPASS.

Từ trang người đàn ông:

> 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.) 
Các vấn đề liên quan