python - 从 python subprocess.call 调用 rsync

标签 python arguments call subprocess rsync

我正在尝试通过 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,则源目录下的所有 文件都同步(不只是 *.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),但在子进程内。调用时,单引号作为文件模式 ("'*.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)

关于python - 从 python subprocess.call 调用 rsync,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14272582/

相关文章:

python - 我怎样才能使列表理解具有 "or?"

python - 在 Python if 语句中使用列表和元组

java - Python 与 Java 性能(运行时速度)

python - 如何在 Python 中向列表添加临时选项并根据用户响应显示元素

c - 文件中此时函数 ' ' 的参数过多

ruby-on-rails - 在 Rails 4 中组织外部 API 调用 - 模块还是类?

Pythonic 参数传递

arrays - 接受任意大小数组作为参数的函数(在 Golang 中可能吗?)

python - 子进程:执行两个或多个preexec_fn

java - 在 Java 中调用方法