我正在尝试将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/'
答案 0 :(得分:1)
可能与cwd
或env
参数有关吗?也许在第一种语法中,它找不到SSH密钥......
答案 1 :(得分: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
获取引号,但不知道它应该如何处理它们;毕竟,它本身并不是一个外壳。
答案 2 :(得分:1)
只是一个建议,您可能更容易使用sh而不是子进程:
import sh
sh.rsync(latestPath, user+"@"+host+":"+dir)