自動化腳本中執行 scp、ssh、ftp 等互動式指令時,需手動輸入密碼,阻礙全自動流程。expect 專為「腳本化互動」設計,可根據提示自動回應。
# CentOS/RHEL yum install -y expect # Ubuntu/Debian apt-get install -y expect # macOS (Homebrew) brew install expect
| 命令 | 說明 |
|---|---|
spawn cmd | 啟動子程序(如 scp) |
expect "pattern" | 等待輸出匹配模式 |
send "string\r" | 發送字串(\r 為 Enter) |
exp_continue | 繼續匹配下一個 expect |
set timeout 秒 | 設定等待逾時 |
interact | 將控制權交還使用者 |
#!/usr/bin/expect
# 檔名:auto_scp.exp
# 用法:./auto_scp.exp local_file user@host:/remote/path
set timeout 20
if {$argc < 2} {
puts "Usage: $argv0 local_file user@host:/remote/path"
exit 1
}
set local_file [lindex $argv 0]
set remote_path [lindex $argv 1]
set password "your_password_here"
set passwd_error 0
spawn scp $local_file $remote_path
expect {
"*assword:*" {
if {$passwd_error == 1} {
puts "Password error"
exit 2
}
send "$password\r"
set passwd_error 1
exp_continue
}
"*(yes/no)?*" {
send "yes\r"
exp_continue
}
timeout {
puts "Connection timeout"
exit 3
}
eof {
# 傳輸完成
}
}
chmod +x auto_scp.exp ./auto_scp.exp ./backup.tar.gz user@192.168.1.50:/home/user/backups/
expect {
-re "Password:" { send "$pwd\r"; exp_continue }
-re "Enter passphrase for key" { send "$key_pass\r"; exp_continue }
-re "Are you sure you want to continue connecting" { send "yes\r"; exp_continue }
-re "Permission denied" { puts "Auth failed"; exit 1 }
timeout { puts "Timeout"; exit 1 }
eof { }
}
#!/usr/bin/expect,而非 #!/bin/bash。set password "pa\$\$w0rd"。set timeout 或在傳輸期望後調整。expect 讓 Shell 腳本具備「人機互動」能力,解決自動化最後一公里問題。但**首選 SSH 金鑰免密登入**,expect 仅作為無法建立金鑰信任時的備選方案。