oli*_*bre 20 string bash echo expansion dollar-sign
bash允许扩展.我说:$'string'
man bash
表格的字是特别对待的.单词扩展为,使用ANSI C标准指定的反斜杠转义字符替换.反斜杠转义序列(如果存在)按如下方式解码: alert(bell) 退格 转义字符 换页 新行 回车 水平制表符 垂直制表符 反斜杠 单引号 双引号 八位字符,其值为八进制值(一到三个)数字) 八位字符,其值为十六进制值
$'string'
string
\a
\b
\e
\E
\f
\n
\r
\t
\v
\
\'
\"
\nnn
nnn
\xHH
HH
(一个或两个十六进制数字) 一个控制字符
\cx
x
扩展结果是单引号,好像美元符号不存在一样.
但为什么庆典不能转化$'\0'
和$'\x0'
成空字符?
有记录吗?有原因吗?(这是一个功能或限制,甚至是一个错误吗?)
$ hexdump -c <<< _$'\0'$'\x1\x2\x3\x4_'
0000000 _ 001 002 003 004 _ \n
0000007
Run Code Online (Sandbox Code Playgroud)
echo
给出了预期的结果:
> hexdump -c < <( echo -e '_\x0\x1\x2\x3_' )
0000000 _ \0 001 002 003 _ \n
0000007
Run Code Online (Sandbox Code Playgroud)
我的bash版本
$ bash --version | head -n 1
GNU bash, version 4.1.2(1)-release (x86_64-redhat-linux-gnu)
Run Code Online (Sandbox Code Playgroud)
为什么echo $'foo\0bar'
不表现echo -e 'foo\0bar'
?
ric*_*ici 24
这是一个限制.bash
不允许字符串值包含内部NUL字节.
Posix(和C)字符串不能包含内部NUL.例如,参见字符串的Posix定义(强调添加):
3.92字符串
由第一个空字节终止并包括第一个空字节的连续字符序列.
类似地,标准C对字符串中的NUL字符有相当明确的说明:
§5.2.1p2...所有位都设置为0的字节,称为空字符,应存在于基本执行字符集中; 它用于终止字符串.
Posix明确禁止/
在文件名(XBD 3.170)或环境变量中使用NUL(和)(XBD 8.1"......被视为以空字节结尾)."
在这种情况下,shell命令语言(包括bash)倾向于使用相同的字符串定义,作为由单个NUL终止的非NUL字符序列.
当然,您可以通过bash管道自由传递NUL,并且没有什么可以阻止您将shell变量分配给输出NUL字节的程序的输出.但是,根据Posix(XSH 2.6.3"如果输出包含任何空字节,则行为未指定."),后果是"未指定的".在bash中,除非使用bash的C-escape语法($'\0'
)将NUL插入到字符串中,否则NUL将被删除,在这种情况下,NUL将最终终止该值.
在实际应用中,请考虑以下两种尝试将NUL插入stdin
实用程序的方法之间的区别:
$ # Prefer printf to echo -n
$ printf $'foo\0bar' | wc -c
3
$ printf 'foo\0bar' | wc -c
7
$ # Bash extension which is better for strings which might contain %
$ printf %b 'foo\0bar' | wc -c
7
Run Code Online (Sandbox Code Playgroud)
但是,为什么不bash的转换
$'\0'
和$'\x0'
成空字符?
因为空字符终止字符串.
$ echo $'hey\0you'
hey
Run Code Online (Sandbox Code Playgroud)