• <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>
            隨筆-159  評論-223  文章-30  trackbacks-0
            腳本概述
               當需要在很多(比如幾十至幾百)臺機器上編譯同一程序時,如果一個個地手工拷貝源碼、再編譯,那么效率就很低,為了能大量節省手工、并行地編譯,因此寫了一個腳本,該腳本基于自動化腳本語言expect(expect基于tcl)實現,基本原理是針對每個遠程主機,創建一個子進程,在該子進程內先調用scp拷貝源碼到遠程主機,再用ssh登錄到遠程主機、發送cd、configure和make命令,交互期間的命令輸出多用正則分析,最終的編譯輸出保存到當前目錄output子目錄下。其命令行參數說明如下:
                第1參數為遠程主機配置文件:一個多行文本文件,每行格式為IP 用戶名 密碼,空格符分隔,支持#注釋。
                第2參數為本地主機源碼目錄:要求該目錄存在Makefile和configure文件。
                第3參數為遠程主機目標目錄:用于存放源碼的位置。

            腳本實現
               拷貝源碼
             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行調用spawn命令執行scp命令,并用catch捕捉錯誤;當執行成功后,第12行用expect等待遠端輸出(超時默認為10秒),第13、14行自動輸入用戶名和密碼,當過程中網絡連接斷開時,會匹配到第8行的eof;當輸出完成連接關閉時,會匹配到第21行的eof;如果輸出太多超過expect內部的buffer時,會匹配到第19行的full_buffer,這里由于為了提高效率,使用了靜默方式的scp,因些實際會匹配到第20行的timeout,不管匹配到哪種情況,都要繼續直到eof。
             
               執行編譯
             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}
               關于spawn和expect的解釋與上節拷貝源碼相同,不同的是依次發送命令cd、source configure、make,每個命令須等到命令提示符后(調用自定義函數wait_cmd)再發下一個,最后發送exit退出ssh、導致連接關閉,匹配到最后一行的eof。對于有的項目源碼,可能沒有或不用配置,那么configure文件可以不存在或內容為空,如果不存在導致報錯也沒關系,不影響make;如果configure出錯,那么make也會出錯。這里使用source是為了使配置在當前shell中生效。
               
               主循環
             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}
               打開遠程主機配置文件,讀取每一行直到文件尾,忽略注釋行,用正則提取IP、用戶名和密碼,創建子進程,按IP和當前時間命名log文件(由于前面調用log_user 0關閉了控制臺輸出,因此為了能記錄輸出到日志文件,一定要加-a選項),最后調用函數copy_file和do_make。
               
               完整腳本下載:autobuild.zip
            posted on 2016-09-28 11:04 春秋十二月 閱讀(3850) 評論(0)  編輯 收藏 引用 所屬分類: System
            国产精品伊人久久伊人电影| 四虎国产精品免费久久| 97精品依人久久久大香线蕉97| 亚洲愉拍99热成人精品热久久| 性欧美丰满熟妇XXXX性久久久| 精品无码久久久久久久动漫| 久久99热只有频精品8| 日本三级久久网| 亚洲色大成网站www久久九| 国产精品一区二区久久精品| 97香蕉久久夜色精品国产 | 久久天堂电影网| 日韩久久久久中文字幕人妻| 久久久久亚洲AV片无码下载蜜桃| 久久经典免费视频| 亚洲日韩欧美一区久久久久我| 久久青草国产精品一区| 久久受www免费人成_看片中文| 久久精品免费一区二区三区| 亚洲国产精品18久久久久久| 亚洲成av人片不卡无码久久| 国产欧美一区二区久久| 亚洲国产欧洲综合997久久| 久久精品国产亚洲av瑜伽| 久久乐国产精品亚洲综合| 99久久国产免费福利| 久久精品无码一区二区三区日韩| 久久青青草原精品国产| 色欲综合久久躁天天躁蜜桃| 久久强奷乱码老熟女网站| 亚洲va中文字幕无码久久| 日日狠狠久久偷偷色综合0| 国产亚州精品女人久久久久久 | 久久久久亚洲av无码专区导航| 亚洲国产精品成人久久蜜臀| 久久国产午夜精品一区二区三区| 久久精品国产99国产精品澳门| avtt天堂网久久精品| 国产精品久久久久久久久免费| 91久久精品国产91性色也| 久久不见久久见免费视频7|