【问题标题】:How do I reliably use Fabric's cd() context manager如何可靠地使用 Fabric 的 cd() 上下文管理器
【发布时间】:2020-08-03 07:00:18
【问题描述】:

我正在尝试在远程系统的目录中运行查找命令。 Fabric 有时会更改目录,但有时会失败,具体取决于路径是否包含括号或空格以及我是否使用 shlex.quote() 。处理这个问题的正确方法是什么?

我的代码基本上是这样的:

from shlex import quote
from fabric import Connection

with Connection(remote_login) as c:
    with c.cd(quote(node.src)):    # Condition 1
    # with c.cd(node.src):         # Condition 2
        result = c.run(r"nice find -maxdepth 1 -type f -printf '%f\n'", echo=True)

如果我使用条件 1,当路径包含括号时它会成功。在这种情况下,Fabric 会生成这一行:

# Fabric output success with parens in path
cd '/data/PixelSizeTestRuby105mm(Zoom248.5mm)' && nice find -maxdepth 1 -type f -printf '%f\n'

但是当路径包含空格时它会失败,因为空格被转义但路径也被引用,而不仅仅是一个或另一个。

# Fabric output failure for spaces in path
cd '/data/Crystal\ Bending\ Test/Bending0' && nice find -maxdepth 1 -type f -printf '%f\n'
sh: line 0: cd: /data/Crystal\ Bending\ Test/Bending0: No such file or directory

如果我改为使用条件 2,则第一个路径失败,第二个路径成功。

# Fabric output failure for parens in path
cd /data/PixelSizeTestRuby105mm(Zoom248.5mm) && nice find -maxdepth 1 -type f -printf '%f\n'
sh: -c: line 0: syntax error near unexpected token `('
sh: -c: line 0: `cd /data/PixelSizeTestRuby105mm(Zoom248.5mm) && nice find -maxdepth 1 -type f -printf '%f\n''

【问题讨论】:

  • 你引用的太多了,要么加单引号,要么加反斜杠,但不能同时加。我隐约猜测这是 Fabric 中的一个错误,但我对此并不熟悉。
  • 无论如何你不必cd;只需将find 的路径作为第一个参数传递,在任何谓词之前。
  • @tripleee 澄清一下,那些带有 cd 命令的例子是 fabric 的输出;它正在形成导致失败的那些命令。我已经编辑了这个问题,试图让这个问题更清楚。我也想知道是不是bug。我想让 cd 上下文处理工作,因为我需要运行其他命令,如 md5sum,如果不先 cd 到目录,我找不到运行的方法。
  • 在将路径传递给 cd 时,您不需要引用 anything。所有的引用都应该纯粹在连接的会话实现内部发生。如果常规(即未引用的)路径字符串失败,则该实现中存在错误。 Fabric/Invoke 似乎没有正确引用括号。

标签: python fabric shlex


【解决方案1】:

这是Invoke implementation 中的一个错误。它根本不为cd 中的路径执行正确的shell 参数转义。

作为一种快速修复,您可以通过在前面添加反斜杠来手动转义路径中的括号。使用shlex.quote 是行不通的,你自己也注意到了。理想情况下,应将 Invoke 实现固定为在内部使用 shlex.quote,而不是它当前执行的临时、有缺陷的手动转义。

【讨论】:

  • 感谢您手动处理的见解和建议。我会检查 Invoke 问题跟踪器。
  • @gazzar 我现在提交了一个带有修复程序的pull request。但该项目的积压工作相当长,因此可能不会很快合并。
  • 太棒了!感谢您也为我节省了提出问题的努力。我已按照您的建议删除了 quote() 并将其替换为一些有针对性的括号转义,我的代码现在似乎表现正常。
猜你喜欢
  • 1970-01-01
  • 2018-03-15
  • 1970-01-01
  • 2019-11-01
  • 2021-09-21
  • 2011-12-25
  • 2018-07-15
  • 2019-05-30
  • 1970-01-01
相关资源
最近更新 更多