【发布时间】:2014-02-15 20:01:36
【问题描述】:
我目前正在尝试执行以下操作:
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
【问题讨论】:
-
请注意,
r'\1'与没有r的'\\1'相同。它们是编写相同字符串的两种方式。 Python 没有添加额外的反斜杠。您看到的是 pdb 以非原始模式打印字符串。 -
您能否在不简化的情况下发布完整的代码,以及您看到的 exact 错误消息?当您遇到逃避问题时,所有层都很重要。
-
您正在转义一个不需要通过使用原始表示法进行转义的字符串 (
cmd = r'string') -
据我了解,您正在远程机器上使用 SSH 使用
sed执行此命令。由于您正在远程编辑或写入文件,因此您可以轻松地使用paramiko.SFTPClient。 -
你为什么用
r''?
标签: python regex python-2.7 escaping