gpt4 book ai didi

python - 双转义字符

转载 作者:太空狗 更新时间:2023-10-30 00:17:30 25 4
gpt4 key购买 nike

我目前正在尝试执行以下操作:

cmd = r'sudo sed -irn "1!N; s/<ip>127.0.0.1<\/ip>(\n.*4000.*)/<ip>0.0.0.0<\/ip>\1/" /usr/something.conf'
subprocess.Popen(cmd)

但是 Popen 提示\\1 是无效引用。在 pdb 中检查它后,我看到了这一点,

'sudo sed -irn "1!N; s/<ip>127.0.0.1<\\/ip>(\\n.*4000.*)/<ip>0.0.0.0<\\/ip>\\1/" /usr/something.conf'

看起来好像 python 正在添加一个额外的 \。有什么方法可以防止这种情况发生,以便我可以像使用 Popen 一样运行命令?

此外,为了简化,我将其排除在示例之外,但这实际上在传递给 Popen 之前被包装在 SSH 调用中,所以是的......它确实需要使用 Popen 完成和 sed

此处的引用是字符串运行的完整步骤链...

def _formatCmd(cmdString, host=None, user=None, keyfile=None):
cmd = []
if host:
cmd.append('ssh')
keyfile = keyfile or getKeyFile()
if keyfile:
cmd.append('-i')
cmd.append(keyfile)
cmd.append("%s@%s" % (user, host))
cmd.append(cmdString)
else:
cmd += cmdString.split()

return cmd


def runCmd(host, user, cmd, timeout=None, cleanup=False):
try:
cmd = _formatCmd(cmd, host=host, user=user)
except:
pass

#create cmd and add it to list of running cmds
proc = Popen(cmd, stdout=PIPE, stderr=PIPE)
runningCmds[proc.pid] = proc

t = threading.Timer(timeout, proc.kill)
t.start()
stdout, stderr = proc.communicate()
t.cancel()

del runningCmds[proc.pid]
return (proc.returncode, stdout, stderr)

cmd = r'sudo sed -irn "1!N; s/<ip>127.0.0.1<\/ip>(\n.*4000.*)/<ip>0.0.0.0<\/ip>\1/" /usr/something.conf'
runCmd('1.1.1.1', 'username', cmd)

返回的确切错误信息是:

sed: -e expression #1, char 59: invalid reference \\1 on `s' command's RHS

最佳答案

问题是 shell 正在做自己的解释/转义。我在使用 cygwin 时发现了类似的东西(在 cygwin 的情况下,shell 是 bash)。

您收到错误的事实:

sed: -e expression #1, char 59: invalid reference \\1 on `s' command's RHS

暗示问题出在方括号 () 而不是 \1 的转义。本质上,它无法找到组,因此您需要转义方括号 \(...\)

要找到原因,诀窍是使用 echo 来调试正在发送的内容:

  1. 将正则表达式简化为一个组和一个匹配项。像这样的东西:

    s/(one)/\1\1/

    其中输入字符串为 'one',预期输出为 oneone

  2. 将您的 cmd 更改为 echo 以便您传递给 shell 的是 echo s/(one)/\1\1/

  3. 我猜您会看到类似 bash: syntax error near unexpected token '(' 的内容。这给了我们线索。基本上,我们需要转义括号。

  4. 现在试试 echo s/\(one\)/\1\1。就我而言,我看到类似的东西

    s/(one)/\1\1
  5. 如果运气好的话,您应该能够将它应用到有问题的表达式中。

使用strong quoting可能是最简单的(用单引号括起来的命令)它告诉 bash 不要解释字符串,尽管您可能仍然需要转义方括号 ()

顺便说一句,对于cygwin,东西需要转义两次,所以实际正确的表达是:

sed s/\\\(one\\\)/\\1\\1/

所以

echo one | sed s/\\\(one\\\)/\\1\\1/

给予

oneone

使用强引号的等价物是:

 echo one | sed 's/\(one\)/\1\1/'

关于python - 双转义字符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21339233/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com