Linux ssh下執行ssh命令遠程登錄其他機器,總是需要輸入密碼,如果人工去登錄,輸入密碼那還可以,但是讓程序自動化登錄遠程ssh服務器,並執行命令着就比較麻煩了。
Linux下有個程序是expect,它可以模擬鍵盤,輸入文本。
1.expect安裝
機器上一般是沒有這個命令的,需要安裝expect:
sudo apt-get install expect
yum install expect
2. expect腳本
經常看到一些腳本有會expect、spawn、send關鍵字,這幾個關鍵字都是在expect程序裏面使用的。
我們來看一個腳本,下面這個腳本ssh遠程連接到節點100.2.12.213,並且cd到指定目錄,然後在目錄中新建名爲“test”的文件夾:#!/usr/bin/expect
set host 100.2.12.213
set user root
set timeout 2
spawn ssh $user@$host
expect "*password:*"
send "111111\r"
expect "*]#"
send "cd /home/caolch \r"
expect "*]#"
send "mkdir test \r"
expect "*]#"
send "exit\r"
expect eof
注意第一行使用的是#!/usr/bin/expect而不是普通的bash腳本那樣。
- expect使用spawn命令來啓動腳本和命令會話,這裏啓動的是ssh命令,這裏的ssh命令將會以子進程的方式產生。
- send用來發送一個字符串,如上面的例子腳本中,我們調用send ”$password\r"就是把密碼發送給SSH連接的服務器端指定端口。
- 與send相反,expect用來等待你所期望的字符串。比如expect "hello"。在expect後面跟的字符串中,你可以指定一個正則表達式。expect會一直等待下去,除非收到的字符串與預期的格式匹配,或者到了超期時間。
- set timeout 2 就是這是超期時間爲2s,如果設置爲-1則永遠等待。
3 shell嵌套expect 命令行
有時候寫個expect腳本比較麻煩,直接只用命令行參數去執行命令,或者嵌套在shell腳本、python腳本中,這樣可以減少expect腳本的數量。
以下的shell腳本的for循環中調用expect命令,ssh連接多個計算機節點執行操作。
HOSTS="100.2.12.213 100.2.12.214"
for host in $HOSTS
do
expect -c "
set timeout 1;
spawn ssh root@${host} -p 22 ;
expect {
yes/no { send \"yes\r\"; exp_continue }
*assword* { send \"111111\r\" }
} ;
expect root@* {send \" mkdir test1 \r\" } ;
expect root@* { send exit\r } ;
expect eof ;
"
done
expect的參數-c後面是字符串,裏面就相當於腳本里面的內容了。
- 用;分號隔開,可以在同一行裏。
- 裏面的"引號,使用\"來代替。
- 第13行的exit最好要有。退出ssh,這樣程序不會阻塞。如果沒有使用,在這個shell命令執行完,無法立刻輸入字符。
- expect腳本必須以interact或expect eof結束,執行自動化任務通常expect eof就夠了
- expect都是使用{},且{ }使用時,前後需要留空格
- 例子使用花括號,表示使用一組並列表達式,只要其中一項符合,就會執行該項,類似switch