bash与dash在命令替换中换行符解析的差异疑问
Bash与Dash在命令替换中换行符处理差异的原因
我发现bash与dash两款POSIX兼容Shell在带引号的命令替换场景下,输出结果存在明显差异,以下是完整测试过程:
测试步骤
- 创建数据文件:
$ echo '"\n"' > data.txt
- 用xxd确认文件字节内容:
$ xxd data.txt 00000000: 225c 6e22 0a "\n".
- 执行bash脚本:
#!/bin/bash data=$(cat data.txt) echo "$data"
输出结果:
$ ./test.bash "\n"
- 执行相同逻辑的dash脚本:
#!/bin/dash data=$(cat data.txt) echo "$data"
输出结果:
$ ./test.dash " "
差异原因解析
这个差异并非来自命令替换本身的换行处理,而是两款Shell的内置echo命令行为不一致导致的:
命令替换的统一行为:
根据POSIX标准,$(command)形式的命令替换会捕获命令的标准输出,并自动移除输出末尾的所有换行符。在本次测试中,data.txt的内容是"\n"加一个换行符,所以命令替换后,data变量的内容都是"\n"(原始字节为22 5c 6e 22),这一步bash和dash的处理完全一致。echo命令的行为差异:
- Bash的内置
echo默认不会解析字符串中的转义序列(如\n),只会原样输出变量内容,因此直接打印"\n"。 - Dash的内置
echo默认会解析转义序列,将\n转换为实际的换行符,因此原本的"\n"被拆分为"、换行、",最终输出两行内容。
验证方法
- 在bash中使用
echo -e "$data",会得到与dash相同的输出(因为-e参数开启转义序列解析)。 - 在dash中使用
printf "%s\n" "$data",会得到与bash相同的输出(因为printf默认不解析转义序列)。
使用版本信息
Dash版本
$ dpkg -s dash Package: dash Essential: yes Status: install ok installed Priority: required Section: shells Installed-Size: 199 Maintainer: Andrej Shadura <andrewsh@debian.org> Architecture: arm64 Multi-Arch: foreign Version: 0.5.12-2 Depends: debianutils (>= 5.6-0.1), dpkg (>= 1.19.1) Pre-Depends: libc6 (>= 2.34) Description: POSIX-compliant shell The Debian Almquist Shell (dash) is a POSIX-compliant shell derived from ash. . Since it executes scripts faster than bash, and has fewer library dependencies (making it more robust against software or hardware failures), it is used as the default system shell on Debian systems. Homepage: http://gondor.apana.org.au/~herbert/dash/
Bash版本
$ bash --version GNU bash, version 5.2.15(1)-release (aarch64-unknown-linux-gnu) Copyright (C) 2022 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software; you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law.
内容的提问来源于stack exchange,提问作者Peter Stace
相关产品推荐
相关产品推荐

