我正在尝试替换文件中的文本
/etc/screenrc
。我尝试了很多方法,但在转义字符串时出现错误。
原字符串是:
termcapinfo xterm 'is=\E[r\E[m\E[2J\E[H\E[?7h\E[?1;4;6l'
我想将其替换为:
termcapinfo xterm* 'is=\E[r\E[m\E[2J\E[H\E[?7h\E[?1;4;6l'
我尝试了以下解决方案(以及许多其他尝试):
- replace:
path: "/etc/screenrc"
regexp: "termcapinfo xterm 'is=\\E[r\\E[m\\E[2J\\E[H\\E[?7h\\E[?1;4;6l'"
replace: "termcapinfo xterm* 'is=\\E[r\\E[m\\E[2J\\E[H\\E[?7h\\E[?1;4;6l'"
我收到的错误如下:
An exception occurred during task execution. To see the full traceback, use -vvv. The error was: re.error: bad escape \E at position 22
fatal: [SERVER_1]: FAILED! => {"changed": false, "module_stderr": "Shared connection to 10.0.0.87 closed.\r\n", "module_stdout": "Traceback (most recent call last):\r\n File \"/root/.ansible/tmp/ansible-tmp-1730351896.8285704-2080135-129908993237357/AnsiballZ_replace.py\", line 107, in <module>\r\n _ansiballz_main()\r\n File \"/root/.ansible/tmp/ansible-tmp-1730351896.8285704-2080135-129908993237357/AnsiballZ_replace.py\", line 99, in _ansiballz_main\r\n invoke_module(zipped_mod, temp_path, ANSIBALLZ_PARAMS)\r\n File \"/root/.ansible/tmp/ansible-tmp-1730351896.8285704-2080135-129908993237357/AnsiballZ_replace.py\", line 47, in invoke_module\r\n runpy.run_module(mod_name='ansible.modules.replace', init_globals=dict(_module_fqn='ansible.modules.replace', _modlib_path=modlib_path),\r\n File \"<frozen runpy>\", line 226, in run_module\r\n File \"<frozen runpy>\", line 98, in _run_module_code\r\n File \"<frozen runpy>\", line 88, in _run_code\r\n File \"/tmp/ansible_replace_payload_nefh4v9s/ansible_replace_payload.zip/ansible/modules/replace.py\", line 324, in <module>\r\n File \"/tmp/ansible_replace_payload_nefh4v9s/ansible_replace_payload.zip/ansible/modules/replace.py\", line 289, in main\r\n File \"/usr/lib/python3.12/re/__init__.py\", line 228, in compile\r\n return _compile(pattern, flags)\r\n ^^^^^^^^^^^^^^^^^^^^^^^^\r\n File \"/usr/lib/python3.12/re/__init__.py\", line 307, in _compile\r\n p = _compiler.compile(pattern, flags)\r\n ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\r\n File \"/usr/lib/python3.12/re/_compiler.py\", line 745, in compile\r\n p = _parser.parse(p, flags)\r\n ^^^^^^^^^^^^^^^^^^^^^^^\r\n File \"/usr/lib/python3.12/re/_parser.py\", line 979, in parse\r\n p = _parse_sub(source, state, flags & SRE_FLAG_VERBOSE, 0)\r\n ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\r\n File \"/usr/lib/python3.12/re/_parser.py\", line 460, in _parse_sub\r\n itemsappend(_parse(source, state, verbose, nested + 1,\r\n ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\r\n File \"/usr/lib/python3.12/re/_parser.py\", line 544, in _parse\r\n code = _escape(source, this, state)\r\n ^^^^^^^^^^^^^^^^^^^^^^^^^^^^\r\n File \"/usr/lib/python3.12/re/_parser.py\", line 443, in _escape\r\n raise source.error(\"bad escape %s\" % escape, len(escape))\r\nre.error: bad escape \\E at position 22\r\n", "msg": "MODULE FAILURE\nSee stdout/stderr for the exact error", "rc": 1}
具体
raise source.error(\"bad escape %s\" % escape, len(escape))\r\nre.error: bad escape \\E at position 22\r\n
有解决办法吗?
我已将其修复如下:
replace:
path: "/etc/screenrc"
regexp: "termcapinfo xterm 'is="
replace: "termcapinfo xterm* 'is="
这就足够了,因为该事件在文件中只有一次。不安全但有效。
发生错误是因为
\E
未记录为有效的转义序列。
您可以使用
\\
反斜杠或 , python 原始字符串表示法:
- replace:
path: "/etc/screenrc"
regexp: "termcapinfo xterm 'is=\\\\E\\[r\\\\E\\[m\\\\E\\[2J\\\\E\\[H\\\\E\\[?7h\\\\E\\[?1;4;6l'"
replace: "termcapinfo xterm* 'is=\\\\E\\[r\\\\E\\[m\\\\E\\[2J\\\\E\\[H\\\\E\\[?7h\\\\E\\[?1;4;6l'"
正则表达式和替换值中的每个
\
都会加倍(例如:\\\\E
)以便正确转义。
替换模式现在使用 xterm* 而不是 xterm。
尝试一下,看看效果如何。
问题是由于 \E 没有在 ansible 中自动处理...所以我们需要为每个使用的 \ 添加 \ 。
- replace:
path: "/etc/screenrc"
regexp: "termcapinfo xterm 'is=\\\\E\\[r\\\\E\\[m\\\\E\\[2J\\\\E\\[H\\\\E\\[?7h\\\\E\\[?1;4;6l'"
replace: "termcapinfo xterm* 'is=\\\\E\\[r\\\\E\\[m\\\\E\\[2J\\\\E\\[H\\\\E\\[?7h\\\\E\\[?1;4;6l'"