【问题标题】:python: subprocess.Popen() behaviourpython: subprocess.Popen() 行为
【发布时间】:2012-09-19 13:34:07
【问题描述】:

我正在尝试将 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/'

【问题讨论】:

  • 如果您使用命令的列表语法,我认为您不需要额外的引号\"。所以你可以: `Popen([ 'rsync', latestPath, '{user}@{host}:{dir}'.format(user=user, host=host, dir=dir) ])
  • @hwjp 如果引号不存在,它如何处理路径中的空格?
  • 第二个也是正确的。即使使用shell=True,子进程也会接受一个数组。事实上,在我的系统上,该命令有效(sourceuserhostdir 的虚拟值。变量的内容是什么?
  • 空格应该没问题。试试看。
  • @HansThen 我添加了变量的示例内容

标签: python subprocess popen


【解决方案1】:

我想知道有什么区别?

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

foo "bar baz"

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

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

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

请注意,在第一种情况下,echo 程序会向您回显引号,而在第二种情况下,shell 在执行 echo 之前已将其剥离。

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

【讨论】:

  • 我想知道为什么它是“询问密码”为“mc@...我认为只是打印有问题:-)
  • @varesa:请将您传递给Popen的列表的确切字符串发布。
  • 列表字符串是什么意思?
  • @varesa: 字符串列表,对不起。
  • 现在既有“加入”的字符串,也有我认为的数组
【解决方案2】:

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

【讨论】:

    【解决方案3】:

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

    import sh
    sh.rsync(latestPath, user+"@"+host+":"+dir)
    

    【讨论】:

    • 我的脚本现在可以运行了,所以我认为我不会过多地触及它。下次我必须做类似的事情时,我会记住这一点
    猜你喜欢
    • 2022-08-23
    • 2019-08-02
    • 1970-01-01
    • 2015-07-19
    • 2013-07-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-11
    相关资源
    最近更新 更多