从python子进程调用rsync。

2024-09-20 23:00:32 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图通过ssh从python脚本中的子进程执行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函数需要一些字符进行转义或其他操作,不是吗?


Tags: homelenincludeargsbookssshexcludersync
1条回答
网友
1楼 · 发布于 2024-09-20 23:00:32

解决了我的问题。我的问题是由于我对subprocess.call函数如何执行的误解以及bash在大括号中扩展列表造成的。

当我在bash shell中发出rsync命令时,bash实际上是将其扩展为多个参数,这些参数被传递给rsync(/shared/books/book_1 shared/books/book_2,等等)。当向subprocess.call函数传递带花括号“/shared/books/{book-1,book-2}”的同一字符串时,扩展没有发生,因为它没有经过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)

相关问题 更多 >

    热门问题