【问题标题】:How can I safely escape a shell command with lots of quotes as a Python string?如何安全地转义带有大量引号作为 Python 字符串的 shell 命令?
【发布时间】:2020-11-30 10:12:55
【问题描述】:

我有以下 awk 命令:

 awk FPAT="([^,]+)|(\"[^\"]+\")" '{ print  $7048 }' ...

我想使用os.system(cmd) 提交它, 但我找不到正确的方法来用所有特殊字符在 python 字符串中编写代码。 以下是我最近的尝试:

 cmd = " awk -v  FPAT=\"([^,]+)|(\\""[^\\""]+\\"")""  ' {{ print   %s  }} '  %s  > %s" .format(c,input,output)

我得到以下结果:

' awk -v  FPAT="([^,]+)|(\\[^\\]+\\)  \' { print   %s  } \'  %s  > %s'

有人可以帮帮我吗?

【问题讨论】:

  • 我会使用原始长字符串。 Example
  • 顺便说一句,您也可以使用原始转义的三引号。 cmd = r''' ...command here... '''

标签: python regex string awk


【解决方案1】:

您可以使用input() 方便地将文本转换为可以复制粘贴到源代码中的字符串:

>>> cmd = input()
 awk FPAT="([^,]+)|(\"[^\"]+\")" '{ print  $7048 }' ...
>>> cmd
' awk FPAT="([^,]+)|(\\"[^\\"]+\\")" \'{ print  $7048 }\' ...'

在 Python 2 中,请改用 raw_input()

顺便说一句,避免使用input 作为变量名,因为它是shadows the builtin input(),并且会使此方法不起作用。


或者,如果文本不包含任何三引号,您可以使用三引号原始字符串:

>>> cmd = r''' awk FPAT="([^,]+)|(\"[^\"]+\")" '{ print  $7048 }' ...'''
>>> cmd
' awk FPAT="([^,]+)|(\\"[^\\"]+\\")" \'{ print  $7048 }\' ...'

感谢Charles Duffy 建议a comment 中的原始字符串选项。

【讨论】:

  • 我们真的不再关心 Python 2 了吗,除非 OP 明确提及?
  • 也就是说,我认为input 对这个问题没有必要;它是关于如何格式化适合与os.system 一起使用的字符串,而不是如何从标准输入中输入字符串。
  • @chepner 这就是我一开始没有提到它的原因。但由于这是一个很小的添加,并且可能会让新手非常困惑,所以我添加了它。
  • @chepner 哦,是的,你是对的,这个问题有点模棱两可。在 OP 的双引号没有正确转义的地方,我认为这就是他们要问的。我进行了编辑以澄清我的意思。
  • 我很困惑。当您使用 re 三引号原始字符串时,为什么 d 输出有 2 个反斜杠?
【解决方案2】:

您将% 运算符使用的占位符与format 方法使用的字段说明符混淆了。

cmd = "awk -v  FPAT=\"([^,]+)|(\\""[^\\""]+\\"")""  ' {{ print   {}  }} '  {}  > {}" .format(c, input, output)

此外,您应该使用subprocess 模块而不是os.system。 Python 可以处理输出重定向,因此您不需要 shell。

with open(output, "w") as f:
    subprocess.run(["awk", "-v", 'FPAT=([^,]+)|("[^\\"]+")', '{{ print {} }}'.format(c), input])

假设 Python 3.6 或更高版本,您可以使用 f 字符串文字简化 awk 脚​​本。

with open(output, "w") as f:
    subprocess.run(["awk", "-v", 'FPAT=([^,]+)|("[^\\"]+")', f'{{ print {c} }}', input])

【讨论】:

    猜你喜欢
    • 2012-06-27
    • 1970-01-01
    • 1970-01-01
    • 2015-10-27
    • 2012-09-18
    • 1970-01-01
    • 2023-04-09
    • 1970-01-01
    • 2020-11-29
    相关资源
    最近更新 更多