雖然 Intel Compiler for Linux 的 install.sh 本來就可以把 binary 安裝到 Debian 裡,不過會使用到 rpm 資料庫;我不喜歡。
因此,我擴充之前作的字串取代 python script,強化成 installer,已測試過 Intel C++ Compiler 與 Intel Fortran Compiler 8.1 與 9.0 版。
以下是這個 script 的內容,檔名請取為 icinst.py :
#!/usr/bin/env python # -*- coding: UTF-8 -*- """ Intel Compiler 安裝指令稿 利用 alien 來把 Intel Compiler 安裝在 Debian 上。 在安裝完畢後,會將: 1. <INSTALLDIR>/bin 目錄內各文字檔內的安裝目錄位置取代為 絕對路徑。 2. <INSTALLDIR>/bin 目錄內各指令稿檔案內, RedHat 系所使 用的 'man -w' 取代為 Debian 使用的 'manpath'。 請利用參數 '-h' 取得詳細的參數說明。 $Id: icinst.py,v 1.1 2005/06/24 04:45:49 yungyuc Exp $ """ import sys, os from popen2 import popen2 __revision__ = "$Revision: 1.1 $".split()[1] class parameters: """ 處理指令行引數。 """ def __init__(self): from optparse import OptionParser, OptionGroup op = OptionParser( usage = "usage: %prog <rpmpackage> <dir>", version = "%prog, " + "%s" % __revision__ ) op.add_option("-f", action="store_true", \ dest="forcedel", default=False, \ help="if destination directory exists, delete it without warning." ) self.op = op (self.options, self.args) = self.op.parse_args() params = parameters() def test_prerequisite( targets ): """ 測試安裝所需的工具是否存在。 """ result = [] for target in targets: so, si = popen2( "whereis %s" % target ) if len(so.read().split()) == 1: result.append( False ) else: result.append( True ) return result def subs(old, new, fn): """ 執行取代工作的函式 old: 被取代字串 new: 新取代字串 fn: 工作的目標檔名 """ import re # 讀取來源資料 f = open( fn, 'r' ); orig = f.read(); f.close() # 執行取代 replaced = re.sub( old, new, orig ) # 把取代後的整筆資料寫回檔案 f = open( fn, 'w' ) f.write( replaced ) f.close() def extract_rpm( rpmfn ): """ 用 alien 把 .rpm 拆開, 傳回暫存目錄 itmp。 """ so, si = popen2( "fakeroot alien -s -d %s" % rpmfn ) tbuf = so.read().split() itmp = tbuf[1] return itmp def install_setpath( itmp, inst_destination ): """ 從 itmp 裡找出包含 'bin', 'lib' 等目錄的父目錄, 據以決定 (isrc, idst) 並且傳回。 """ for root, dirs, filenames in os.walk( itmp ): if "bin" in dirs: skel = "" while root != itmp: root, tail = os.path.split(root) skel = os.path.join( tail, skel ) isrc = os.path.join(itmp, skel)[:-1] idst = os.path.join(inst_destination, skel)[:-1] while True: try: os.renames( isrc, idst ) break except OSError, (errno, strerror): if errno == 39: if not params.options.forcedel: sys.stderr.write( "[ERROR] destination dir '%s' not empty, " "clean up tmp dir '%s' \n" % ( idst, itmp ) ) os.system( "rm -rf %s" % itmp ) sys.exit(39) else: sys.stderr.write( "[WARN] destination dir '%s' not empty, " "but I am forced to delete it anyway\n" % idst ) os.system( "rm -rf %s" % idst ) return isrc, idst def install( rpmsrc, inst_destination ): """ 安裝 .rpm 到指定的目錄。 """ sys.stdout.write( "Extracting %s\n" % rpmsrc ) itmp = extract_rpm( rpmsrc ) isrc, idst = install_setpath( itmp, inst_destination ) # 掃瞄 bin 裡的檔案型態 so, si = popen2( 'file %s' % os.path.join(idst, "bin", '*') ) fns = [] for line in so.readlines(): tokens = line.split(':') fns.append( tokens[:2] ) sys.stdout.write( "Substituting '<INSTALLDIR>' with proper idst (%s) for: \n" % os.path.abspath(idst) ) for fn, des in fns: if des.find('text') != -1: subs("<INSTALLDIR>", os.path.abspath(idst), fn) sys.stdout.write( " \""+os.path.basename(fn)+"\"" ) sys.stdout.write( "\nin %s .\n" % os.path.join(idst, "bin")) sys.stdout.write( "Substituting 'man -w' with 'manpath' for: \n" ) for fn, des in fns: if des.find('shell script') != -1: subs("man -w", "manpath", fn) sys.stdout.write( " \""+os.path.basename(fn)+"\"" ) sys.stdout.write( "\nin %s .\n" % os.path.join(idst, "bin")) os.system( "rm -rf %s" % itmp ) sys.stdout.write( "Installed at %s\n" % idst ) def main(): """ 主函式。 """ # 檢查必要的工具程式 prs = 'fakeroot', 'alien' sys.stdout.write( "Tools" ) for pr in prs: sys.stdout.write( " '%s'" % pr ) sys.stdout.write( " would be used to do the installation.\n" ) rprs = test_prerequisite( prs ) missing = False for pr, rpr in zip(prs,rprs): if rpr == False: sys.stdout.write( "[ERROR] tool '%s' missing.\n" % pr ) missing = True if missing: sys.exit(5) sys.stdout.write( "\n" ) if len(params.args) < 2: sys.stdout.write( "please specify correct parameters.\n\n" ) params.op.print_help() sys.exit(-1) else: install( params.args[0], params.args[1] ) if __name__ == '__main__': main()
Posted by yungyuc
at 22:04,
0 comment,
0 trackback.
Navigate
- Previous: Plone Shell @2005/06/22
- Next: 賜名 @2005/06/24
Add a trackback
Please send trackback to: http://blog.seety.org/everydaywork/2005/6/24/365/trackback/.
Add a comment