zoukankan      html  css  js  c++  java
  • 使用expect在script中切换到root用户(精华)

    使用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
    "
    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
    "
    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 '1i "123"' /root/test.txt
    3         expect {
    4                 "*yes/no*" {send "yes
    "; exp_continue}
    5                 "*password*" {send "123456
    "; exp_continue}
    6                 "*Password*" {send "123456
    ";}
    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
    "                   #发送密码,别忘了以
    结尾
    12 
    13 expect "*#*"                         #等待#提示符的出现
    14 
    15 send    "ls -l>/tmp/1
    "             #执行ls命令,并重定向到/tmp/1
    16 
    17 expect "*#*"                         #等待#出现,说明上一个命令执行完毕了
    18 
    19 send     "uname -a>/tmp/2
    "      #再执行下一条命令
    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
    "
     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 " 7 expect "#" 8 interact
    复制代码

    6.吼吼

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

    7.一个小哥的总结:

    复制代码
     1 昨天一个网友问如何能够将输入密码的工作在shell里面自动完成,研究了一下,发现这种交互式的工作,普通的shell实现不了,据说可以借助expect来搞定,所以初步学习了一下expect,成果和大家分享一下:
     2 
     3 应用一:
     4 实现从普通用户“test”切换到root用户,自动输入root的密码,不用在终端提示符下执行密码输入操作。
     5 步骤:
     6 (1)vi autosu.sh
     7 (2)#!    /usr/bin/expect      -f   //指定expect工具的路径,如果不清楚具体路径,可以用"which expect"命令来查看。
     8 spawn    su   -                     //  在expect 中用"spawn"关键字来调用命令“su - ” 
     9 expect     ":"                     //在执行了su   -  命令之后,提示输入密码的提示符。例如你在执行了su - 命令之后,终端里面会出现提示“口令:”,那么你就可以在这里写expect    ":",或者expect    -exact    "口令:"
    10 send     "rootpasswd
    "          //这里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
    "       //这里expect用send将你的root密码自动输入到上面的提示符之后。
    25 expect   "#"                 //当遇到提示符以#结尾时,即为root权限时;
    26 send      "ls
    "             //expect  用spend方法调用ls 命令,并且回车(“
    ”)
    27 expect   "#"
    28 send   "sh  aaa.sh
    "        //调用sh aaa.sh,即执行一个脚本文件aaa.sh。
    29 expect    "#"
    30 send   "echo  $?
    "
    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 " 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 " 30 expect "]#" 31 send "cd /root " 32 expect "]#" 33 send "sh t.sh " 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
    ";}
    48         "yes/no" {send "yes
    "; 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
    "
     6 #expect "#"
     7 #send "touch /root/jj.ll
    "
     8 expect "#"
     9 send "/home/Nemuadmin/realtime_task/goms_file_del.sh &
    "
    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
    ";}
     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
    复制代码
  • 相关阅读:
    ImagView
    Menu(二)在代码中add
    Menu菜单键(一)
    不区分大小写
    ASP.NET中的一些小技巧
    常用的CSS标签标记属性翻译注释
    页面自动刷新和自动跳转代码
    ASP.NET中利用存储过程实现模糊查询
    打开页面时光标自动在输入框
    一些页面自动跳转的实现
  • 原文地址:https://www.cnblogs.com/lgj8/p/12982087.html
Copyright © 2011-2022 走看看