...
http://os.51cto.com/art/200912/167898.htm
方法一:
http://www.nginx.cn/1934.html
shell腳本需要交互的地方可以使用here文檔是實現,但是有些命令卻需要用戶手動去就交互如passwd、scp
對自動部署免去用戶交互很痛苦,expect能很好的解決這類問題。
expect的核心是spawn expect send set
spawn 調用要執行的命令
expect 等待命令提示信息的出現,也就是捕捉用戶輸入的提示:
send 發送需要交互的值,替代了用戶手動輸入內容
set 設置變量值
interact 執行完成后保持交互狀態,把控制權交給控制台,這個時候就可以手工操作了。如果沒有這一句登錄完成后會退出,而不是留在遠程終端上。
expect eof 這個一定要加,與spawn對應表示捕獲終端輸出信息終止,類似於if....endif
expect腳本必須以interact或expect eof結束,執行自動化任務通常expect eof就夠了。
設置expect永不超時
set timeout -1
設置expect 300秒超時,如果超過300沒有expect內容出現,則推出
set timeout 300
expect編寫語法,expect使用的是tcl語法。
一條Tcl命令由空格分割的單詞組成. 其中, 第一個單詞是命令名稱, 其余的是命令參數
cmd arg arg arg
$符號代表變量的值. 在本例中, 變量名稱是foo.
$foo
方括號執行了一個嵌套命令. 例如, 如果你想傳遞一個命令的結果作為另外一個命令的參數, 那么你使用這個符號
[cmd arg]
雙引號把詞組標記為命令的一個參數. "$"符號和方括號在雙引號內仍被解釋
"some stuff"
大括號也把詞組標記為命令的一個參數. 但是, 其他符號在大括號內不被解釋
{some stuff}
反斜線符號是用來引用特殊符號. 例如:\n 代表換行. 反斜線符號也被用來關閉"$"符號, 引號,方括號和大括號的特殊含義
expect使用實例
1。首先確認expect的包要安置。
#rpm -qa | grep expect
如果沒有則需要下載安裝,
#yum install expect
2.安裝完成后,查看expect的路徑,可以用
#which expect
/usr/bin/expect
3.編輯腳本
#vi autosu.sh
添加如下內容
#!/usr/bin/expect -f //這個expect的路徑就是用which expect 查看的結果 spawn su - nginx //切換用戶 expect "password:"//提示讓輸入密碼 send "test\r"//輸入nginx的密碼 interact //操作完成
4.確定腳本有可執行權限
chmod +x autosu.sh
5.執行腳本 expect autosu.sh 或 ./autosu.sh
expect常用腳本
登陸到遠程服務器
#!/usr/bin/expect set timeout 5set server [lindex $argv 0]set user [lindex $argv 1]set passwd [lindex $argv 2] spawn ssh -l $user $server expect {"(yes/no)"{ send "yes\r"; exp_continue }"password:"{ send "$passwd\r"}} expect "*Last login*" interact
scp拷貝文件
#!/usr/bin/expectset timeout 10set host [lindex $argv 0]//第1個參數,其它2,3,4參數類似set username [lindex $argv 1]set password [lindex $argv 2]set src_file [lindex $argv 3]set dest_file [lindex $argv 4] spawn scp $src_file $username@$host:$dest_file expect {"(yes/no)?"{ send "yes\n" expect "*assword:"{ send "$password\n"}}"*assword:"{ send "$password\n"}} expect "100%" expect eof
使用方法
./expect_scp 192.168.75.130 root 123456 /root/src_file /root/dest_file
以上的命令執行后,將把本地/root目錄下的src_file文件拷貝到用戶名為root,密碼為123456的主機192.168.75.130中的/root下,同時還將這個源文件重命名為dest_file
======================================================
http://www.cnblogs.com/haochuang/archive/2012/05/18/2507457.html
一、簡便切換用戶:
切換用戶,每次輸入密碼,比較麻煩,可以使用腳本交互式登錄實現,每次只要輸入./su_ 並tab,執行此腳本,即可切換至root用戶,比較簡單。如下:
hao@hao-ubuntu:~$ cat su_root.sh
#!/usr/bin/expect
set timeout 3
spawn su
expect "Password:"
exec sleep 1
send "root\r"
expect "#"
interact
hao@hao-ubuntu:~$ ./su_root.sh
spawn su
Password:
root@hao-ubuntu:/home/hao#
當然也可以增加一些if判斷之類,讓其他用戶切換也不必輸入密碼。具體根據個人喜歡自己修改完善。
二、交互式登錄:
通過expect,實現交互式登錄,且看如下腳本:
hao@hao-ubuntu:~$ cat login.sh
#!/usr/bin/expect -f
set ipaddr "192.168.77.58"
set passwd "hao"
spawn ssh hao@$ipaddr
#spawn 意思是執行命令,expect內命令,shell中不存在
expect {
"yes/no" { send "yes\r"; exp_continue}
"password:" { send "$passwd\r" }
}
#expect "]# "
#echo '----------------login $ipaddr SUCC!--------------'
#send "touch a.txt\r"
#意思為發送命令
#send "exit\r"
expect eof
exit
===========================================
另外嘗試修改sh,或者alias,使其隨處可以調用,而不是只能到固定位置執行腳本才可以,或許更為優化。
當然此腳本稍微可以帶來便利,但是也存在安全風險。
補充一點內容:
對如上內容可以詳細解釋如下:expect spawn、linux expect 用法
使用expect實現自動登錄的腳本,網上有很多,可是都沒有一個明白的說明,初學者一般都是照抄、收藏。可是為什么要這么寫卻不知其然。本文用一個最短的例子說明腳本的原理。
腳本代碼如下:
##############################################
#!/usr/bin/expect
set timeout 30
spawn ssh -l username 192.168.1.1
expect "password:"
send "ispass\r"
interact
##############################################
1. [#!/usr/bin/expect]
這一行告訴操作系統腳本里的代碼使用那一個shell來執行。這里的expect其實和linux下的bash、windows下的cmd是一類東西。
注意:這一行需要在腳本的第一行。
2. [set timeout 30]
基本上認識英文的都知道這是設置超時時間的,現在你只要記住他的計時單位是:秒
3. [spawn ssh -l username 192.168.1.1]
spawn是進入expect環境后才可以執行的expect內部命令,如果沒有裝expect或者直接在默認的SHELL下執行是找不到spawn命令的。所以不要用 “which spawn“之類的命令去找spawn命令。好比windows里的dir就是一個內部命令,這個命令由shell自帶,你無法找到一個dir.com 或 dir.exe 的可執行文件。
它主要的功能是給ssh運行進程加個殼,用來傳遞交互指令。
4. [expect "password:"]
這里的expect也是expect的一個內部命令,有點暈吧,expect的shell命令和內部命令是一樣的,但不是一個功能,習慣就好了。這個命令的意思是判斷上次輸出結果里是否包含“password:”的字符串,如果有則立即返回,否則就等待一段時間后返回,這里等待時長就是前面設置的30秒
5. [send "ispass\r"]
這里就是執行交互動作,與手工輸入密碼的動作等效。
溫馨提示: 命令字符串結尾別忘記加上“\r”,如果出現異常等待的狀態可以核查一下。
6. [interact]
執行完成后保持交互狀態,把控制權交給控制台,這個時候就可以手工操作了。如果沒有這一句登錄完成后會退出,而不是留在遠程終端上。如果你只是登錄過去執行
#!/usr/bin/expect #注意安裝的路徑,不確定 whereis expect 一下
# Change a login shell to bash
set user [lindex $argv 0]
spawn bash $user
expect "]:"
send "/bin/bash "
expect eof
exit
使用expect自動登錄
一,什么是expect?
在做系統管理時,我們很多時候需要輸入密碼,例如:連接 ssh,連接ftp,
那么如何能做到不輸入密碼嗎?
我們需要有一個工具,能代替我們實現與終端的交互,
那么,就是它:expect,管理員的最好的朋友之一
它能夠代替我們實現與終端的交互,我們不必再守候在電腦旁邊輸入密碼,
或是根據系統的輸出再運行相應的命令,
這些都可以由expect代替我們來完成
說明:expect到底是什么?
expect是一種腳本語言,使用起來非常簡單,我們看后面的例子即可以了解到了
三,安裝expect
備注:因為expect是基於tcl的,所以需要你的系統中安裝有tcl
如何檢查?
[root@dev ~]# whereis tcl
tcl: /usr/lib/tcl8.4 /usr/share/tcl8.4
如果看不到結果,請先安裝tcl
安裝,
[root@dev ~]# yum install expect
也可以從http://rpm.pbone.net下載for相應發行版的rpm包
補充部分詳見http://blog.csdn.net/ysdaniel/article/details/7059511
http://www.jbxue.com/article/1121.html
3. 自動ssh/scp腳本
如果需要從A,到B,然后才能夠到C,那么需要ssh和scp兩次,是比較麻煩的。
ssh自動登錄:
#!/usr/bin/expect -f
set timeout 30
spawn ssh weiqiong@B
expect "password:"
send "ppppppr"
expect "]*"
send "ssh weiqiong@Cr"
expect "password:"
send "ppppppr"
interact
scp從A拷貝文件到C:
#!/usr/bin/expect -f
set timeout 300
set file [lindex $argv 0]
spawn scp $file weiqiong@B:/home/weiqiong
expect "password:"
send "ppppppr"
expect "]*"
spawn ssh weiqiong@B
expect "password:"
send "ppppppr"
expect "]*"
send "scp $file weiqiong@C:/home/weiqiongr"
expect "password:"
send "ppppppr"
expect "]*"
exit
interact
scp從C拷貝文件到A:
#!/usr/bin/expect -f
set timeout 300
set file [lindex $argv 0]
spawn ssh weiqiong@B
expect "password:"
send "ppppppr"
expect "]*"
send "scp weiqiong@C:/home/weiqiong/$file .r"
expect "password:"
send "ppppppr"
expect "]*"
send "exitr"
expect "]*"
spawn scp weiqiong@B:/home/weiqiong/$file .
expect "password:"
send "ppppppr"
interact
4. 建立ssh/scp通道
比如說我的機器是A,中間服務器為B,目標服務器是C
從A可以ssh到B,從B可以ssh到C,但是A不能直接ssh到C
現在展示利用ssh通道技術從A直接傳輸文件到C
1. ssh -L1234:C:22 userid@B
input B's password
(1234是本機A的空閑端口,該指令需要A機器上的root用戶權限,實際上是在本機1234端口建立了一個通道)
2. 打開一個新的console,鍵入:
scp -P1234 filename userid@localhost:
input C's password
https://www.centos.bz/2012/11/scp-ssh-auto-login-with-expect/
下面給出scp和ssh的使用示例:
1、scp
- expect -c "
- spawn scp root@1.2.3.4:/root/1.log /root
- expect {
- \"*assword\" {set timeout 300; send \"password\r\";}
- \"yes/no\" {send \"yes\r\"; exp_continue;}
- }
- expect eof"
2、ssh
- #!/bin/bash
- expect -c "
- spawn ssh root@192.168.1.204 \"ls;\"
- expect {
- \"*assword\" {set timeout 300; send \"password\r\";}
- \"yes/no\" {send \"yes\r\"; exp_continue;}
- }
- expect eof
- "
http://bbs.chinaunix.net/thread-1288757-1-1.html
#!/usr/bin/expect spawn /usr/bin/ssh root@10.99.0.245 expect "*password:" send "123456\r" expect "*]#" send "cd /root" expect "*]#" send "exit\r" expect eof 能看懂吧。我就是連進去后執行了一個cd命令。 你可以把你的shell單獨寫一個腳本,在這里嵌套一下就行 |
================================================
http://www.yunsec.net/a/school/xtrm/linux/2010/1025/6456.html
今天blinux問我如何實現在shell中使用su切換自動輸入密碼的問題,Google了一下,發現了expect這個好東西,寫了個簡單的demo:
#!/usr/bin/expect
set timeout 30
spawn su -
expect “Password:”
send “rootroot\r”
interact
從shell的寫法上就很明顯的看到,expect也是類似一個shell環境。基本寫法就是spawn后跟需要自動匹配輸入的命令,然后expect后跟匹配的文本,send發送需要手動輸入的文本。interact表示切換至root之后保持交互,如果沒有則仍會退至原用戶的shell。
方法二:
http://bbs.chinaunix.net/thread-569443-2-1.html
就是expect,perl,python都是用的這個模塊,讀入密碼,然后自動發送過去
http://www.icodelogic.com/?p=33
對於這兩個問題,有一個比較簡單的解決方案,那就是管道。
管道其實是一種重定向技術,Linux所提供的管道符“|”將兩個命令隔開,管道符左邊命令的輸出就會作為管道符右邊命令的輸入。連續使用管道意味着第一個命令的輸出會作為第二個命令的輸入,第二個命令的輸出又會作為第三個命令的輸入,依此類推。
現在,我們先來看看如何使用管道來為我們自動輸入密碼:
echo 123456 | sudo -S command
這里有兩條指令,前面一條是輸出123456(假設這就是你的密碼),而后面的指令就是取得管理員權限,它會提示你輸入密碼。這里由於采用管道提示符,自動的將前面的密碼輸入給第二條指令,所以現在你就自動完成了密碼的輸入任務啦。用這種方式雖然密碼是明文存在腳本中,不太安全,但是勝在方法簡單。
然后,對第二種情況,同樣采用管道命令:
echo ‘show database’ | mysql -u root -p ***
這里就自動的將show database輸入到進入SQL后的新的命令提示符后面,這條命令現在是可以自動執行了的。
http://www.taobaotest.com/blogs/show/57
在編寫shell腳本的批處理代碼時,一般只要求用戶在調用shell時,輸入有限的幾個參數,然后由shell進行批處理作業,在批處理作業完成之前,中途不會有任何打斷。但是linux有些命令本身是要求進行人機交互的,命令基本上是以一問一答形式在終端上跟用戶交互,如passwd、smbpasswd,在設置某個用戶的密碼時,傳入username參數,回車后系統要求輸入密碼,而smbpasswd還要求再次輸入確認密碼,這樣就需要人工干預2次,這個命令才能執行完畢。
有沒有什么辦法不用用戶干預,由系統模擬用戶完成輸入操作呢?答案是肯定的,就是利用linux的管道技術,通過“echo”命令進行標准輸出,然后通過管道符“|”轉換為passwd和smbpasswd的標准輸入,由此模擬人機交互,具體實現:
#通過設定--stdin參數,指明接受標准輸入;