use*_*645 2 bash escaping bsdtar
这不起作用:
$ tar -cf /tmp/z.tar -C /space/myroot -s '/^\.svn\/patches/__patches' src .svn/patches
tar: Invalid regular expression: trailing backslash (\)
Run Code Online (Sandbox Code Playgroud)
也没有好处:
$ tar -cf /tmp/z.tar -C /space/myroot -s '/^\\.svn\\/patches/__patches' src .svn/patches
tar: Invalid replacement flag _
Run Code Online (Sandbox Code Playgroud)
反斜杠(最多 4 个)和引号的每种组合都会给我带来这两个错误之一。不过我知道第一个在 sed 中有效:
$ tar -cf /tmp/z.tar -C /space/myroot src .svn/patches
$ tar -tf /tmp/z.tar | sed 's/^\.svn\/patches/__patches/'
src/a.c
src/b.c
__patches/A.patch
__patches/B.patch
Run Code Online (Sandbox Code Playgroud)
我也知道我可以逃避并这样做:
$ tar -cf /tmp/z.tar -C /space/myroot -s '/^.svn.patches/__patches' src .svn/patches
Run Code Online (Sandbox Code Playgroud)
——但我真的不想这么做。
来自man bsdtar:
-s 模式
....
其中 old 是基本正则表达式
...
基本正则表达式应该与\/. 遗憾的bsdtar是这里写得不正确,并且不能正确处理转义。
end_pattern = strchr(rule_text + 1, *rule_text);
Run Code Online (Sandbox Code Playgroud)
rule_text是一个字符串char *,它与您传递给选项的字符串一起传递-s,因此它具有 string /^\.svn\/patches/__patches。应该end_pattern指向模式的最后一个字符(即指向 的/in from /__patches)。然而,由于使用了简单的 strchr,因此使用第一个/找到的字符( 中的字符\/),无论是否转义,都会使用它。错误:
tar: Invalid regular expression: trailing backslash (\)
Run Code Online (Sandbox Code Playgroud)
来自regcomp尝试解析正则表达式^\.svn\(因为这是两者之间剥离的部分/)。因为尾随反斜杠后面没有任何内容\由于表达式中人们可以考虑向 bsdtar 开发人员发布错误报告,但这可能并不值得修复。
请注意, 的语法-s是/old/new/。/模式中有一个尾随,您丢失了。最后/您可以指定标志。
不过,您可以通过以下方式解决该问题:
bsdtar -s '#\.svn/patches#__patches#'
Run Code Online (Sandbox Code Playgroud)
任何字符都适用于/.