• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            隨筆-162  評(píng)論-223  文章-30  trackbacks-0
            腳本概述
               當(dāng)需要在很多(比如幾十至幾百)臺(tái)機(jī)器上編譯同一程序時(shí),如果一個(gè)個(gè)地手工拷貝源碼、再編譯,那么效率就很低,為了能大量節(jié)省手工、并行地編譯,因此寫了一個(gè)腳本,該腳本基于自動(dòng)化腳本語言expect(expect基于tcl)實(shí)現(xiàn),基本原理是針對(duì)每個(gè)遠(yuǎn)程主機(jī),創(chuàng)建一個(gè)子進(jìn)程,在該子進(jìn)程內(nèi)先調(diào)用scp拷貝源碼到遠(yuǎn)程主機(jī),再用ssh登錄到遠(yuǎn)程主機(jī)、發(fā)送cd、configure和make命令,交互期間的命令輸出多用正則分析,最終的編譯輸出保存到當(dāng)前目錄output子目錄下。其命令行參數(shù)說明如下:
                第1參數(shù)為遠(yuǎn)程主機(jī)配置文件:一個(gè)多行文本文件,每行格式為IP 用戶名 密碼,空格符分隔,支持#注釋。
                第2參數(shù)為本地主機(jī)源碼目錄:要求該目錄存在Makefile和configure文件。
                第3參數(shù)為遠(yuǎn)程主機(jī)目標(biāo)目錄:用于存放源碼的位置。

            腳本實(shí)現(xiàn)
               拷貝源碼
             1proc copy_file {host user srcdir dstdir passwd {to 10} } {
             2    if [catch "spawn scp -rq $srcdir $user@$host:$dstdir" msg] {
             3        send_error "failed to spawn scp: $msg\n"
             4        exit 1
             5    }
             6    
             7    set timeout $to
             8    expect_after eof { 
             9        send_error "$host scp died unexpectedly\n"
            10        exit 1
            11    }
            12    expect {
            13        "(yes/no)?" { send "yes\r"; exp_continue }
            14        -re "(?:P|p)assword:" { send "$passwd\r" }
            15        timeout { do_timeout "$host scp" }
            16    }
            17
            18    expect {
            19        full_buffer { exp_continue }
            20        timeout { exp_continue }
            21        eof 
            22    }
            23}
               第2行調(diào)用spawn命令執(zhí)行scp命令,并用catch捕捉錯(cuò)誤;當(dāng)執(zhí)行成功后,第12行用expect等待遠(yuǎn)端輸出(超時(shí)默認(rèn)為10秒),第13、14行自動(dòng)輸入用戶名和密碼,當(dāng)過程中網(wǎng)絡(luò)連接斷開時(shí),會(huì)匹配到第8行的eof;當(dāng)輸出完成連接關(guān)閉時(shí),會(huì)匹配到第21行的eof;如果輸出太多超過expect內(nèi)部的buffer時(shí),會(huì)匹配到第19行的full_buffer,這里由于為了提高效率,使用了靜默方式的scp,因些實(shí)際會(huì)匹配到第20行的timeout,不管匹配到哪種情況,都要繼續(xù)直到eof。
             
               執(zhí)行編譯
             1proc do_make {host user passwd subdir {to 10} } {
             2    if [catch {spawn ssh $user@$host} msg ] {
             3        send_error "failed to spawn ssh: $msg\n"
             4        exit 1
             5    }
             6    
             7    set timeout $to
             8    expect_after eof { 
             9        send_error "$host ssh died unexpectedly\n"
            10        exit 1
            11    }
            12    
            13    expect {  
            14        "*yes/no" { send "yes\r"; exp_continue }
            15        -re "(?:P|p)assword:" { send "$passwd\r" }  
            16        timeout { do_timeout "$host ssh" }
            17    }  
            18    wait_cmd $spawn_id passwd
            19
            20    send "cd $subdir\r"  
            21    wait_cmd $spawn_id cd
            22    
            23    send "source configure\r"
            24    wait_cmd $spawn_id configure
            25
            26    send "make\r"  
            27    wait_cmd $spawn_id make
            28
            29    send "exit\r"  
            30    expect eof  
            31}
               關(guān)于spawn和expect的解釋與上節(jié)拷貝源碼相同,不同的是依次發(fā)送命令cd、source configure、make,每個(gè)命令須等到命令提示符后(調(diào)用自定義函數(shù)wait_cmd)再發(fā)下一個(gè),最后發(fā)送exit退出ssh、導(dǎo)致連接關(guān)閉,匹配到最后一行的eof。對(duì)于有的項(xiàng)目源碼,可能沒有或不用配置,那么configure文件可以不存在或內(nèi)容為空,如果不存在導(dǎo)致報(bào)錯(cuò)也沒關(guān)系,不影響make;如果configure出錯(cuò),那么make也會(huì)出錯(cuò)。這里使用source是為了使配置在當(dāng)前shell中生效。
               
               主循環(huán)
             1set f [open $file r]
             2set curtime [clock seconds]
             3
             4log_user 0
             5set s {[:blank:]}
             6set pattern "^(\[^#$s]+)\[$s]+(\[^$s]+)\[$s]+(\[^$s]+)"
             7
             8while { [gets $f line] != -1 } {
             9    if { ![regexp $pattern [string trimleft $line] ? host user passwd] } {
            10        continue
            11    }
            12    send_user "$host $user $passwd\n"
            13    if { ![fork] } {
            14        
            15        set filename output/${host}_[clock format $curtime -format %y.%m.%d_%H.%M.%S].log
            16        log_file -noappend -a $filename
            17
            18        copy_file $host $user $srcdir $dstdir $passwd 30
            19        do_make $host $user $passwd $subdir 30
            20
            21        send_user "$host finish\n"
            22        exit
            23    }
            24}
               打開遠(yuǎn)程主機(jī)配置文件,讀取每一行直到文件尾,忽略注釋行,用正則提取IP、用戶名和密碼,創(chuàng)建子進(jìn)程,按IP和當(dāng)前時(shí)間命名log文件(由于前面調(diào)用log_user 0關(guān)閉了控制臺(tái)輸出,因此為了能記錄輸出到日志文件,一定要加-a選項(xiàng)),最后調(diào)用函數(shù)copy_file和do_make。
               
               完整腳本下載:autobuild.zip
            posted on 2016-09-28 11:04 春秋十二月 閱讀(3857) 評(píng)論(0)  編輯 收藏 引用 所屬分類: System
            久久久久久夜精品精品免费啦| 久久精品国产网红主播| 国产福利电影一区二区三区久久老子无码午夜伦不 | 久久久久久国产精品免费免费| 欧美久久综合性欧美| 久久夜色精品国产亚洲av| 亚洲色欲久久久综合网东京热| 久久精品成人免费看| 青青草国产97免久久费观看| 国产精品一久久香蕉产线看| 美女久久久久久| 热久久国产精品| 人妻无码中文久久久久专区| 久久久久国色AV免费看图片| 久久精品国产久精国产思思| 亚洲а∨天堂久久精品| 久久青草国产手机看片福利盒子 | 国产99久久久国产精免费| 久久久无码人妻精品无码| 一级做a爰片久久毛片免费陪 | 国内精品久久久久影院老司| 99久久精品国产综合一区| 久久久久亚洲Av无码专| 国产69精品久久久久观看软件| 久久久久亚洲?V成人无码| 久久国产乱子精品免费女| 久久午夜伦鲁片免费无码| 日韩精品久久久肉伦网站| 区亚洲欧美一级久久精品亚洲精品成人网久久久久 | 亚洲乱码日产精品a级毛片久久| 亚洲国产二区三区久久| 亚洲欧洲日产国码无码久久99| 亚洲欧美国产精品专区久久 | 91精品日韩人妻无码久久不卡| 久久99国内精品自在现线| 久久久一本精品99久久精品88| 伊人久久大香线蕉综合影院首页| 欧美精品福利视频一区二区三区久久久精品| 久久精品国产精品青草app| 色综合久久精品中文字幕首页| 久久精品一区二区|