我最近编写了一个脚本,我想在将文件作为参数传递给另一个命令之前使用 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