使用expect在script中切換到root用戶


1.尚觀版本

http://www.uplook.cn/biancheng/133/1335040/

 1     a. 命令行: /usr/bin/expect -c "set timeout -1; spawn su; expect \"Password:\"; send \"123456\\r\"; interact"
 2 
 3     b. 腳本:
 4 
 5         #!/usr/bin/expect
 6         set timeout 5
 7         spawn su
 8         expect "Password:"
 9 
10         send "123456\r"
11         interact
12 
13         #expect "# "
14 
15         #send "whoami"

---------------------------------------------------------------------------------------------------------------------------------

2.網絡小生的疑問(與我遇到的一樣)

sutoRoot.sh 腳本:

#-----------------------------------------------#
#!/usr/bin/expect

#
# Su to Root without entering password manually !
#

spawn su -
expect "Password:"
send "lovexia\r"
expect eof

#-----------------------------------------------#

執行的情況:

[nic@lovexia ~]$ who am i
nic      pts/0        2008-09-19 02:30 (192.168.2.81)           -----> 用戶為nic
[nic@lovexia ~]$ ./sutoRoot.sh
spawn su -
Password:
[root@lovexia ~]# who am i      ---> 已經su 成 Root 了,但執行who am i 后停了一會就自動變成下面的樣子了,退回到用戶nic 了
[nic@lovexia ~]$ who am i            
nic      pts/0        2008-09-19 02:30 (192.168.2.81)
[nic@lovexia ~]$

對expect 還不熟,請教了 !

一位網友的解答:

1 expect eof  ========> interact

3.一位網友的資源(http://bbs.chinaunix.net/thread-1733075-1-1.html)

1 expect -c "
2 spawn /usr/bin/ssh -t -l squall $IPADDR sudo sed -i '1\i "123"' /root/test.txt
3         expect {
4                 \"*yes/no*\" {send \"yes\r\"; exp_continue}
5                 \"*password*\" {send \"123456\r\"; exp_continue}
6                 \"*Password*\" {send \"123456\r\";}
7         }
8 expect eof;"

4.使用expect腳本登錄到root賬號並執行命令

 1 通過expect腳本登錄root賬號,方法比較簡單,只要先寫一個如下格式的腳本即可:
 2 
 3 #!/usr/bin/expect
 4 
 5 set timeout=30                       #設置30秒超時
 6 
 7 spwan su root
 8 
 9 expect "Password*"
10 
11 send    "123456\r"                   #發送密碼,別忘了以\r結尾
12 
13 expect "*#*"                         #等待#提示符的出現
14 
15 send    "ls -l>/tmp/1\r"             #執行ls命令,並重定向到/tmp/1
16 
17 expect "*#*"                         #等待#出現,說明上一個命令執行完畢了
18 
19 send     "uname -a>/tmp/2\r"      #再執行下一條命令
20 
21 #interact                            #使用interact后,腳本將退出到root賬號下,可以手動執行root權限的命令
22 
23 expect  eof           
24 
25 exit

5.我寫的這個Expect程序,用來su root用戶,為什么不行?(http://bbs.chinaunix.net/forum.php?mod=viewthread&tid=2265473

 1 寫了一個Expect程序:su_root
 2 #!/usr/bin/expect
 3 
 4 set timeout 3
 5 
 6 spawn su
 7 expect "assword:"
 8 send "szcj\r"
 9 expect "#"
10 interact
11 
12 執行后,結果
13 
14 ./su_root
15 spawn su
16 Password: szcj
17 (這里還有一個空行)
18 
19 應該不是Expect的配置問題,我寫了一個Expect程序,自動Telnet登陸別的服務器,能正常執行的。
20 
21 為什么回這樣?
這樣就可以了:
1
set timeout 3 2 3 spawn su 4 expect "Password:" 5 exec sleep 1 6 send "szcj\r" 7 expect "#" 8 interact

6.吼吼

1     #!/usr/bin/expect
2     spawn  su -
3     expect 'assword: '
4     send "NiDeRootMiMa\r"
5     interact

7.一個小哥的總結:

 1 昨天一個網友問如何能夠將輸入密碼的工作在shell里面自動完成,研究了一下,發現這種交互式的工作,普通的shell實現不了,據說可以借助expect來搞定,所以初步學習了一下expect,成果和大家分享一下:
 2 
 3 應用一:
 4 實現從普通用戶“test”切換到root用戶,自動輸入root的密碼,不用在終端提示符下執行密碼輸入操作。
 5 步驟:
 61)vi autosu.sh
 72)#!    /usr/bin/expect      -f   //指定expect工具的路徑,如果不清楚具體路徑,可以用"which expect"命令來查看。
 8 spawn    su//  在expect 中用"spawn"關鍵字來調用命令“su - ” 
 9 expect     ":"                     //在執行了su   -  命令之后,提示輸入密碼的提示符。例如你在執行了su - 命令之后,終端里面會出現提示“口令:”,那么你就可以在這里寫expect    ":",或者expect    -exact    "口令:"
10 send     "rootpasswd\r"          //這里expect用send將你的root密碼自動輸入到上面的提示符之后。
11 interact                            //操作完成。
12 
13 注意:這里強調一下執行腳本時要注意的地方,不能按照習慣來用sh ***.sh來這行expect的程序,會提示找不到命令,因為expect用的不是bash所以會報錯。執行的時候直接./***.sh就可以了。~切記!
14 
15 
16 
17 
18 
19 應用二:
20 從普通用戶切換到root之后,執行“ls”操作,調用執行aaa.sh,返回執行結果,間隔10S。
21 #/usr/bin/expect    -f
22 spawn  su  -                //  在expect 中用"spawn"關鍵字來調用命令“su - ” 
23 expect  ":"                  //在執行了su   -  命令之后,提示輸入密碼的提示符。例如你在執行了su - 命令之后,終端里面會出現提示“口令:”,那么你就可以在這里寫expect    ":",或者expect    -exact    "口令:" 
24 send    "rootpasswd\r"       //這里expect用send將你的root密碼自動輸入到上面的提示符之后。
25 expect   "#"                 //當遇到提示符以#結尾時,即為root權限時;
26 send      "ls\r"             //expect  用spend方法調用ls 命令,並且回車(“\r”)
27 expect   "#"
28 send   "sh  aaa.sh\r"        //調用sh aaa.sh,即執行一個腳本文件aaa.sh。
29 expect    "#"
30 send   "echo  $?\r"
31 sleep 10
32 interact
33 
34 
35 先寫這些,可能不對。

8.一位猛人的闡述:

現代的Shell對程序提供了最小限度的控制(開始,停止,等等),而把交互的特性留給了用戶。 這意味着有些程序,你不能非交互的運行,比如說passwd。 
有一些程序可以非交互的運行,但在很大程度上喪失了靈活性,比如說fsck。這表明Unix的工具構造邏輯開始出現問題。Expect恰恰填補了其中的一些裂痕,解決了在Unix環境中長期存在着
的一些問題。
Expect使用Tcl作為語言核心。不僅如此,不管程序是交互和還是非交互的,Expect都能運用。這是一個小語言和Unix的其他工具配合起來產生強大功能的經典例子。 舉個例子,假如你是一個“懶”人,每天要做重復的工作,而偏偏你不想“ 做”。所以,你想到一個“偷懶”的辦法就是腳本工具。執行完腳本,你可以一邊喝着茶一邊收獲着結果。這是事物美好
的一面,另一面自然就不那么美好了,也許 shell需要跟你交流才能完成(也就是我們常說的交互)。這時,你就得想起神奇的expect。使用方法如下:
a.在終端下輸入autoexpect命令,然后會看到autoexpect started, file is script.exp的提示信息。這時,你已經進入了自動的命令錄制中,把你想要做的事兒全部做一遍,這個
工具會詳細的記錄下來,並寫入script.exp文件中;當你確定完成時,輸入exit退出“錄制”。會看到autoexpect done, file is script.exp的提示信息,說明錄制成功。script.exp
是一個文本文件,可以用vim或者emacs打開查看,也可以根據自己的需要進行相應的修改,前提是符合規則。
上面提到的是用自動的方法使用expect,同樣也可以手動寫腳本來執行。腳本以#!/usr/bin/expect開頭,提出expect命令存放的路徑,也可以執行which expect獲得。下面是一個簡單
的例子實現shell的切換:
12 #!/usr/bin/expect 13 # Change a login shell to tcsh 14 spawn chsh 15 expect "]:" 16 send "/bin/tcsh\r" 17 expect eof 18 19 保存為filename.sh文件,添加執行權限,./filename.sh后就可以看到結果。有點感覺吧。。。不要着急,好東西還在后面呢! 20 21 記得Linux里切換用戶的命令吧,對了,就是su。如果你想從普通用戶切換到root,然后再繼續做操作。請接着往下看: 22 23 #!/usr/bin/expect 24 25 set user [lindex $argv 0] 26 set passwd [lindex $argv 1] 27 spawn su - $user 28 expect "" 29 send "$passwd\r" 30 expect "]#" 31 send "cd /root\r" 32 expect "]#" 33 send "sh t.sh\r" 34 interact 35 36 可以把你想傳的參數一並寫在后面,如./filename.sh root 123456,argv[0]為root,argv[1]為123456。
spawn以expect的方式執行命令,然后expect發現該行以“:”結束時,會用send傳遞要執行的命令與shell交互;最后,interact命令給把控制權交給你所切換的用戶

9.Expect 手冊中文版

http://blog.csdn.net/classwang/article/details/3928467

10.怎么在expect里面交互兩次

http://bbs.chinaunix.net/forum.php?mod=viewthread&tid=2333695

 


11.我自己總結的:

  目的:定期刪除GOMS機中測量文件。

  背景:GOMS機為諾西定制linux只讀系統。沒法加入任何啟動腳本。

  方法:FEWS機為可制定linux系統。在FEWS中利用腳本A加入定時任務,在每月的1,10,20日的20:00點調用腳本B。腳本B會SSH到每個GOMS中調用腳本C,腳本C會

首先切到root用戶(只有root用戶能刪除文件),然后調用腳本D執行清理任務。

  缺點:腳本D效率不夠高,但是我懶得改了。

腳本A:

 1 #!/bin/bash
 2 
 3 crontab -r
 4 
 5 echo "00 20 1,10,20 * * /root/kobe/call_goms_file_del.sh" > /root/kobe/crontab_task
 6 
 7 crontab /root/kobe/crontab_task
 8 
 9 crontab -l
10 exit 0

 

 

腳本B:

 1 #/bin/bash
 2 #########################
 3 #1.SSH every GOMS,Call the function script.
 4 #2.touch log
 5 ###########################
 6 call_goms_file_del_log_file=/root/kobe/call_goms_file_del.log
 7 
 8 del_cmd=""
 9 
10 function log()
11 {
12         echo -e "$(date  +'%Y-%m-%d %T ') $*" >> $call_goms_file_del_log_file
13 }
14 
15 
16 if [ -f "$call_goms_file_del_log_file" ]; then
17         log $call_goms_file_del_log_file exilt!
18         del_cmd=$(date | awk '$3==1{printf("rm -f /root/kobe/call_goms_file_del.log")}')
19         log del_cmd:$del_cmd
20         if [ "${del_cmd}" != "" ]; then
21                 ${del_cmd}
22                 log recreat $call_goms_file_del_log_file...
23                 touch $call_goms_file_del_log_file
24         fi
25 
26 else
27         log $call_goms_file_del_log_file not exilt,creating...
28         touch $call_goms_file_del_log_file
29 fi
30 
31 
32 
33 log "Let's go..."
34 
35 goms_IP_list[1]='Nemuadmin@10.56.19.30'
36 goms_IP_list[2]='Nemuadmin@10.56.19.28'
37 goms_IP_list[3]='Nemuadmin@10.56.19.26'
38 
39 
40 for x in ${goms_IP_list[*]}
41 do
42     log "Enter $x"
43 expect -c "
44     spawn  ssh $x /home/Nemuadmin/realtime_task/goms_file_del.sh
45 
46     expect {
47         \"*assword\" {set timeout 21600; send \"nemuuser\r\";}
48         \"yes/no\" {send \"yes\r\"; exp_continue;}
49     }
50 expect eof"
51 
52 done
53 
54 log "It is over!."
55 echo "----------------------------------------------------------------------------------" >> $call_goms_file_del_log_file
56 exit 0

 

 

腳本C:

 1 #!/usr/bin/expect
 2 
 3 spawn su
 4 expect ":"
 5 send "password\r"
 6 #expect "#"
 7 #send "touch /root/jj.ll\r"
 8 expect "#"
 9 send "/home/Nemuadmin/realtime_task/goms_file_del.sh &\r"
10 expect "#"
11 
12 interact
13 
14 #expect eof
15 
16 exit

 

 

腳本D:

 

  1 #!/bin/bash
  2 
  3 logfile="/home/Nemuadmin/realtime_task/goms_file_del.log"
  4 
  5 function log()
  6 {
  7   echo -e "$(date  +'%Y-%m-%d %T ') $*" >> $logfile
  8 }
  9 
 10 
 11 #expect -c "
 12 #        spawn su
 13 #        expect  {
 14 #                \"Password: \" {send \"password\r\";}
 15 #        }
 16 #interact"
 17 
 18 if [ -f "$logfile" ]; then
 19     log $logfile exist!
 20 else
 21     log $logfile not exist,creating...
 22     touch $logfile
 23     chmod 777 $logfile
 24 fi
 25 
 26 echo "----------------------Start time : $(date  +'%Y-%m-%d %T ')--------------------------------------" > $logfile
 27 
 28 #get date
 29 year=$(date +%Y)
 30 log "Year:$year!"
 31 
 32 month=$(date +%m)
 33 log "Month:$month!"
 34 
 35 day=$(date +%d)
 36 log "Day:$day!"
 37 
 38 
 39 ##################################################
 40 #argc:1
 41 #argv:directory
 42 #function:delete the files under argv parameter
 43 ##################################################
 44 function file_del()
 45 {
 46     log "cd $1"
 47     cd $1    
 48     for i in *.gz
 49     do 
 50         #get file's date
 51         file_date=$(echo $i | cut -d "." -f4)
 52         log "file[$i] file_date: $file_date!"    
 53             
 54         file_year=${file_date:0:4}
 55 #        log "file_year:$file_year "
 56         
 57         file_month=${file_date:4:2}
 58 #        log "file_month:$file_month "
 59         
 60         file_day=${file_date:6:2}
 61 #        log "file_day:$file_day "
 62         
 63 #        if ((  (year > file_year) || ((month > file_month) && ((((month - file_month) * 30 + day) - file_day) > 10 ) ) )  )) ;then
 64 #            del_flag="Delete"
 65 #        else
 66 #            del_flag="Nodelete"
 67 #        fi
 68     
 69     
 70         del_flag=$(awk -v year=$year -v month=$month -v day=$day -v file_year=$file_year -v file_month=$file_month -v file_day=$file_day 'BEGIN{
 71                 if ( (year > file_year) || ((month > file_month) && ((((month - file_month) * 30 + day) - file_day) > 10 ) ) ) 
 72                 printf("Delete")
 73                else
 74             printf("Nodelete")}')
 75         
 76 #        log "File($i) del_flag:$del_flag"
 77         if [[ $del_flag == "Delete" &&  $i != "*.gz"  ]];then
 78             log "Delete file :[$i]!"
 79             rm -f $i
 80         else
 81             log "File :[$i] Nodelete!"
 82         fi
 83         echo  "-------------------------------------------------------------------------------" >> $logfile
 84     done
 85 }
 86 
 87 #DELETE files under /var/opt/OMSftproot/xmlfiles directory
 88 cd /var/opt/OMSftproot/xmlfiles/
 89 file_del "/var/opt/OMSftproot/xmlfiles/"
 90 
 91 #DELETE files under /var/opt/OMSftproot/xmlfilesBU directory
 92 cd /var/opt/OMSftproot/xmlfilesBU/
 93 
 94 for j in $(ls)
 95 do
 96     cd /var/opt/OMSftproot/xmlfilesBU/
 97     file_del "$j"
 98 done
 99 
100 #done successfully.
101 log "It is over!."
102 exit 0

 

 

 

 

 

 

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM