簡體   English   中英

從python subprocess.call調用rsync

[英]calling rsync from python subprocess.call

我正在嘗試從python腳本中的子進程執行ssh上的rsync,以將圖像從一個服務器復制到另一個服務器。 我有一個函數定義為:

def rsyncBookContent(bookIds, serverEnv):
    bookPaths = ""
    if len(bookIds) > 1:
        bookPaths = "{" + ",".join(("book_"+str(x)) for x in bookIds) + "}"
    else:
        bookPaths = "book_" + str(bookIds[0])

    for host in serverEnv['content.hosts']:
        args = ["rsync", "-avz", "--include='*/'", "--include='*.jpg'", "--exclude='*'", "-e", "ssh", options.bookDestDir + "/" + bookPaths, "jill@" + host + ":/home/jill/web/public/static/"]
        print "executing " + ' '.join(args)
        subprocess.call(args)

我最終要做的是讓Python執行這個(它來自bash shell):

rsync -avz --include='*/' --include='*.jpg' --exclude='*' -e ssh /shared/books/{book_482,book_347} jill@10.12.27.20:/home/jill/web/public/static/

確實,我的印刷聲明輸出:

executing rsync -avz --include='*/' --include='*.jpg' --exclude='*' -e ssh /shared/books/{book_482,book_347} jill@10.12.27.20:/home/jill/web/public/static/

但是當從這個python腳本中執行時,有兩個問題:

  1. 如果len(bookIds)> 1,/ shared / books /下的子目錄列表會被bash或rsync錯誤地解釋。 錯誤消息是:
    • rsync:link_stat“/ shared / books / {book_482,book_347}”失敗:沒有這樣的文件或目錄(2))
  2. 如果len(bookIds)== 1,源目錄下的所有文件都是rsynced(不僅僅是* .jpg,我的意圖)

看起來好像subprocess.call函數需要轉義一些字符或什么,不是嗎?

找出我的問題。 我的問題是由於我誤解了subprocess.call函數的執行方式以及bash在花括號內擴展列表的結果。

當我在bash shell中發出帶有大括號子目錄的rsync命令時,bash實際上將它擴展為多個參數,這些參數被傳遞給rsync(/ shared / books / book_1 shared / books / book_2等)。 將帶有大括號“/ shared / books / {book_1,book_2}”的相同字符串傳遞給subprocess.call函數時,擴展沒有發生,因為它沒有經過bash,所以我對rsync的論證確實是“/ shared / books / {book_1,book_2}”。

類似地,文件模式('*','* .jpg'等)周圍的單引號在bash命令行上起作用(只有單引號內的值傳遞給rsync),但在subprocess.call中,單引號作為文件模式(“'* .jpg'”)傳遞給rsync。

新的(工作)代碼如下所示:

def rsyncBookContent(bookIds, serverEnv):
    bookPaths = []
    for b in bookIds:
        bookPaths.append(options.bookDestDir + "/book_" + str(b))
    args = []
    for host in serverEnv['content.hosts']:
        # copy all *.jpg files via ssh
        args = ["rsync", "-avz", "--include", "*/", "--include", "*.jpg", "--exclude", "*", "-e", "ssh"]
        args.extend(bookPaths)
        args.append("jill@" + host + ":/home/jill/web/public/static/"])
        print "executing " + ' '.join(args)
        subprocess.call(args)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM