3

我正在尝试将 rsync 与 python 一起使用。我读过将参数​​传递给 Popen 的首选方法是使用数组。

我试过的代码:

p = Popen(["rsync",
        "\"{source}\"".format(source=latestPath),
        "\"{user}@{host}:{dir}\"".format(user=user, host=host, dir=dir)],
        stdout=PIPE, stderr=PIPE)

结果是 rsync 要求输入密码,即使我已经设置了 SSH 密钥来进行身份验证。

我认为这是执行新进程的环境的问题。我接下来尝试的是:

p = Popen(["rsync", 
   "\"{source}\"".format(source=latestPath),
   "\"{user}@{host}:{dir}\"".format(user=user, host=host, dir=dir)],
   stdout=PIPE, stderr=PIPE, shell=True)

这导致 rsync 打印“正确用法”,因此参数被错误地传递给 rsync。我不确定这是否应该工作(传递一个带有 shell=True 的数组)

如果我像这样完全删除数组:

p = Popen("rsync \"{source}\" \"{user}@{host}:{dir}\"".format(
        source=latestPath, user=user, host=host, dir=dir),
      stdout=PIPE, stderr=PIPE, shell=True)

该程序运行良好。为了这个脚本,这真的没关系,但我想知道有什么区别?为什么其他两个(主要是第一个)不起作用?

难道只是需要shell环境,第二个不对?

编辑:变量的内容

latestPath='/home/tomcat/.jenkins/jobs/MC 4thworld/workspace/target/FourthWorld-0.1-SNAPSHOT.jar'
user='mc'
host='192.168.0.32'
dir='/mc/test/plugins/'
4

3 回答 3

1

可能与cwdorenv参数有关吗?也许在第一种语法中,它找不到 SSH 密钥......

于 2012-09-19T13:42:13.350 回答
1

我想知道有什么区别?

当 时shell=True,整个命令被传递给 shell。引号在那里,因此 shell 可以再次正确地选择命令。特别是通过

foo "bar baz"

到 shell 会导致它将命令解析为(Python 语法)['foo', 'bar baz'],以便它可以执行foo带有参数的命令bar baz

相比之下,当 时shell=False,Python 会立即将列表中的参数传递给程序。例如,尝试以下subprocess命令:

>>> import subprocess
>>> subprocess.call(["echo", '"Hello!"'])
"Hello!"
0
>>> subprocess.call('echo "Hello!"', shell=True)
Hello!
0

请注意,在第一种情况下,程序会向您回显引号echo,而在第二种情况下,shell 在执行echo.

在您的特定情况下,rsync获取引号但不知道应该如何处理它们;毕竟,它本身并不是一个外壳。

于 2012-09-19T14:50:55.420 回答
1

只是一个建议,您可能更容易使用sh而不是子进程:

import sh
sh.rsync(latestPath, user+"@"+host+":"+dir)
于 2012-09-20T08:15:45.010 回答