bash 中进程替换的输出重复 ^A 字符

bash 中进程替换的输出重复 ^A 字符

我最近编写了一个脚本,我想在将文件作为参数传递给另一个命令之前使用 sed 修改文件:

$ some-command <(sed $'s\x01foo\x01bar\x01g' some-file)

此操作失败并出现以下错误:

sed: -e expression #1, char 8: unknown option to `s'

经过一些实验,我发现 bash在调用 sed 之前复制了^A( ) 字符:\x01

$ cat -v <(echo $'\x01')
^A^A

对于 ^B(或其他)字符,不会发生这种情况。

$ cat -v <(echo $'\x02')
^B

此行为记录在哪里?这是某些默认设置的结果,其中 ^A 用于模糊功能吗?

我在我可以访问的四个不同版本的 bash 中看到了这一点:4.1.2、4.2.25、4.2.46 (linux) 和 4.3.42 (cygwin)

答案1

是的,\x01在参数扩展内部使用时会重复:

$ cat -v <(echo $'\x01')
^A^A

在 2.05 之后的 bash 版本中也会发生这种情况:

$ ./script
zsh/sh          : ^A
b203sh          : ^A
b204sh          : ^A
b205sh          : ^A
b30sh           : ^A^A
b32sh           : ^A^A
b41sh           : ^A^A
b42sh           : ^A^A
b43sh           : ^A^A
b44sh           : ^A^A
ksh93           : ^A
attsh           : ^A
zsh/ksh         : ^A
zsh             : ^A

这不会发生在管道中:

$ echo $'\x01' | cat -v
^A

解决方法:

因此,也许您可​​以将代码重写为:

$ echo $'\x01' | some-command

或者:

$ some-command <(sed $'s\x02foo\x02bar\x02g' some-file)

答案2

这已经是去年二月报告为错误去年九月又是一次。有一个注释关于Bash git 树中的修复在后面的讨论中。

^A/\001和 DEL/ ^?/都会发生这种情况\177,但似乎需要$'...'在进程内进行替换,因此您可以使用以下方法来解决它"$(printf "...")"

不好:

$ od -c  <( echo -n  $'\x01_\x7f' ) 
0000000 001 001   _ 001 177
0000005

好的:

$ od -c  <( echo -n  "$(printf '\x01_\x7f')" )
0000000 001   _ 177
0000003

相关内容