【linux 】 解決腳本中scp需要手動輸入密碼問題

1、解決方法? ? ? ??
? ? ? ? 命令行scp拷貝文件需要輸入密碼,如果想在腳本里自動化scp拷貝,可以用expect來實現(xiàn)自動化操作。
例子1.1:
將本機/home/test.txt文件拷貝到目標機器xx.xx.xx.xx的/home目錄下
#!/bin/bash
function scp_file {
? ?local file=$1
? ?local passwd="xxxxxx" ? ?# xx.xx.xx.xx機器的密碼
? ?expect -c"
? ? ? ?spawn scp -r ${file} root@xx.xx.xx.xx:/home
? ? ? ?expect {
? ? ? ? ?\"*assword\" {set timeout 300; send \"${passwd}\r\";}
? ? ? ?}
? ? ? ?expect eof"
}
scp_file "/home/test.txt"
2、知識點
2.1 expect工具
expect命令可以用于處理自動交互場景,比如scp時,讓你手動輸入密碼,使用expect就可以自動輸入密碼,避免手動輸入。
expect中有定義一些命令,做如下總結(jié):
expect: expect工具的內(nèi)部命令。它的主要功能是判斷上一次輸出結(jié)果里是否含有“xxxx”指定的字符串。
spawn: spawn時進入expect環(huán)境后才可以執(zhí)行的expect內(nèi)部命令,它的主要功能時用來傳遞交互指令。
send:發(fā)送信息,模擬用戶手動輸入這一過程,最后要添加\r。表示返回到當前行的最開始位置。
exp_continue: 使用exp_continue之后,會重新從當前expect塊的開始重新執(zhí)行。
expect eof: 執(zhí)行完expect中的命令后退出。
3、遇到的問題
3.1 expect: spawn id exp4 not open while executing "expect eof"
原因:spawn出來的進程在expect eof的時候,已經(jīng)結(jié)束了。
解決方法:
檢查expect eof之前,spawn生成的進程是否已經(jīng)結(jié)束。
以例子1.1說明,如果程序修改為如下樣子,就會報錯:expect: spawn id exp4 not open while executing "expect eof",而將exp_continue;刪除就不會報錯。
#!/bin/bash
function scp_file {
? ?local file=$1
? ?local passwd="xxxxxx" ? ?# xx.xx.xx.xx機器的密碼
? ?expect -c"
? ? ? ?spawn scp -r ${file} root@xx.xx.xx.xx:/home
? ? ? ?expect {
? ? ? ? ?\"*assword\" {set timeout 300; send \"${passwd}\r\"; exp_continue;}
? ? ? ?}
? ? ? ?expect eof"
}
scp_file "/home/test.txt"
這是因為expect已經(jīng)執(zhí)行了一次,exp_continue會重新執(zhí)行一次expect塊,而前一次的expect已經(jīng)處理了spawn這個進程的返回值,你再重新執(zhí)行,spawn生成的進程已經(jīng)結(jié)束了,因此報錯。刪掉exp_continue,處理完就退出,不要再循環(huán)執(zhí)行expect了。