python
  • syntax
  • scripting
  • process
  • 2009-01-07 35 views 3 likes 
    3

    我有一個調用各種參數的可執行程序Python腳本(在這個例子中,它是「sqlpubwiz.exe」,這是「Microsoft SQL Server數據庫發佈嚮導」):在Python中,我如何使用子進程而不是os.system?

    import os 
    
    sqlpubwiz = r'"C:\Program Files\Microsoft SQL Server\90\Tools\Publishing\sqlpubwiz.exe"' 
    server = 'myLocalServer' 
    database = 'myLocalDatabase' 
    connection_values = ['server=' + server, 'database=' + database, 'trusted_connection=true'] 
    connection_string = ';'.join(connection_values) 
    dbms_version = '2000' 
    sqlscript_filename = 'CreateSchema.sql' 
    
    args = [ 
         sqlpubwiz, 
         'script', 
         '-C ' + connection_string, 
         sqlscript_filename, 
         '-schemaonly', 
         '-targetserver ' + dbms_version, 
         '-f', 
    ] 
    
    cmd = ' '.join(args) 
    os.system(cmd) 
    

    此代碼運行正確,但我想養成使用subprocess的習慣,因爲它打算取代os.system。但是,經過幾次失敗嘗試後,我似乎無法正常工作。

    如何將上面的代碼看起來一樣,如果它被轉換到位使用os.system的使用子?

    回答

    5
    import subprocess 
    p=subprocess.Popen(args, stdout=subprocess.PIPE) 
    print p.communicate()[0] 
    

    它看起來差不多。但是路徑不應該是'''不管路徑是什麼'「。因爲那給了我一個錯誤。你想要「避開反斜線的路徑」或者「沒有逃脫的路徑」。

    另外ARGS應該是這樣的形式的[ '-arg', 'ARGS']代替[ 'ARG argsval']。

    +0

    我想,但我得到了以下錯誤:WindowsError:[錯誤3]系統找不到指定的路徑 – 2009-01-07 17:34:49

    +0

    我覺得POPEN需要ARGS作序,而不是一個大的空間分隔的字符串。嘗試傳遞'args'而不是'cmd'。 – 2009-01-07 17:45:43

    +0

    刪除引號允許腳本執行時沒有錯誤,但沒有創建sql文件。我怎樣才能看到一個exe的控制檯輸出? – 2009-01-07 17:55:01

    4

    從可執行文件的名稱中刪除引號。在您的示例的第一線,而不是

    sqlpubwiz = r'"C:\Program Files\Microsoft SQL Server\90\Tools\Publishing\sqlpubwiz.exe"' 
    

    使用:

    sqlpubwiz = r'C:\Program Files\Microsoft SQL Server\90\Tools\Publishing\sqlpubwiz.exe' 
    

    那是因爲你沒有逃避什麼,因爲一個shell不會涉及。

    就用subprocess.call(args)(不join的指定參數時,將它們作爲一個列表)

    如果你想捕獲輸出(os.system不能做到這一點),只要按照subprocess文檔:

    result = subprocess.Popen(args, stdout=subprocess.PIPE).communicate()[0] 
    print result 
    
    -1

    請記住,使用os.system使用了外殼,所以你必須真傳

    shell=True 
    

    到POPEN合作nstructor/call來正確模擬它。當然,你可能實際上不需要shell,但它確實需要。

    0

    這不是直接回答你的問題的答案,但我認爲這可能有幫助。

    如果您希望更細粒度地控制異常處理返回的內容等,您還可以查看pexpect。我曾經用過這種情況,我所說的過程並不一定以正常狀態信號退出,或者我想更多地與它進行交互。這是一個非常方便的功能。

    4

    下面是基於Carlos Rendon(和nosklo)幫助和建議我修改後的代碼:

    # import os 
    import subprocess  
    
    sqlpubwiz = r'C:\Program Files\Microsoft SQL Server\90\Tools\Publishing\sqlpubwiz.exe' 
    server = 'myLocalServer' 
    database = 'myLocalDatabase' 
    connection_values = ['server=' + server, 'database=' + database, 'trusted_connection=true'] 
    connection_string = ';'.join(connection_values) 
    dbms_version = '2000' 
    sqlscript_filename = 'CreateSchema.sql'  
    
    args = [ 
          sqlpubwiz, 
          'script', 
          '-C', 
          connection_string, 
          sqlscript_filename, 
          '-schemaonly', 
          '-targetserver', 
          dbms_version, 
          '-f', 
        ] 
    
    # cmd = ' '.join(args) 
    # os.system(cmd) 
    
    subprocess.call(args) 
    

    (注:包含所需空間的原始參數值轉換成單獨的列表項)

    4

    僅供參考,subprocesslist2cmdline()功能,可以讓你看到Popen將要使用的字符串。

    你的版本給:

    '"C:\\Program Files\\Microsoft SQL Server\\90\\Tools\\Publishing\\sqlpubwiz.exe" script "-C server=myLocalServer;database=myLocalDatabase;trusted_connection=true" CreateSchema.sql -schemaonly "-targetserver 2000" -f' 
    

    周圍"-C server=myLocalServer;database=myLocalDatabase;trusted_connection=true""-targetserver 2000"額外的引號。

    正確格式化:

    args = [ 
         sqlpubwiz, 
         'script', 
         '-C', connection_string, 
         sqlscript_filename, 
         '-schemaonly', 
         '-targetserver', dbms_version, 
         '-f', 
    ] 
    

    給出:

    '"C:\\Program Files\\Microsoft SQL Server\\90\\Tools\\Publishing\\sqlpubwiz.exe" script -C server=myLocalServer;database=myLocalDatabase;trusted_connection=true CreateSchema.sql -schemaonly -targetserver 2000 -f' 
    

    此外,未成年點,但它是一個好習慣,使序列,如args不需要是可變進元組,而不是列表。

    0

    Windows命令將接受正斜槓「/」代替反斜槓的路徑名,這樣你就可以用前者,以避免在您的命令字符串轉義反斜線。不完全是你的問題的答案,但也許有用的知道。

    相關問題