• <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>
            隨筆-161  評論-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 春秋十二月 閱讀(3856) 評論(0)  編輯 收藏 引用 所屬分類: System
            国产精品久久午夜夜伦鲁鲁| 国产精品久久久久久久久鸭| AA级片免费看视频久久| 久久精品草草草| 精品久久久久中文字幕一区| 武侠古典久久婷婷狼人伊人| 亚洲国产精品无码久久久蜜芽| 激情伊人五月天久久综合| 色综合色天天久久婷婷基地| 天天影视色香欲综合久久| 久久99精品久久只有精品| 国产精品va久久久久久久| 欧美国产成人久久精品| 欧美伊香蕉久久综合类网站| 伊人 久久 精品| 亚洲午夜久久久精品影院| 久久亚洲熟女cc98cm| 99精品久久久久久久婷婷| 久久妇女高潮几次MBA| 国产午夜精品久久久久九九电影| 2019久久久高清456| 青草影院天堂男人久久| 久久亚洲中文字幕精品有坂深雪| 91麻豆精品国产91久久久久久| 亚洲精品美女久久久久99| 伊人久久无码精品中文字幕| 国产日产久久高清欧美一区| 97精品国产97久久久久久免费| 久久亚洲av无码精品浪潮| 国产精品免费久久| 久久亚洲精品中文字幕三区| 777米奇久久最新地址| 国产毛片欧美毛片久久久| 中文字幕精品无码久久久久久3D日动漫| 天天躁日日躁狠狠久久| 伊人久久大香线焦AV综合影院| 天堂无码久久综合东京热| 久久久午夜精品| 7777精品伊人久久久大香线蕉| 久久人人爽人人爽人人片AV不| 欧美激情一区二区久久久|