$ a='a
'
$ echo -n "$a" | md5sum
60b725f10c9c85c70d97880dfe8191b3 -
$ echo -n "$a" > foo
$ cat foo | md5sum
60b725f10c9c85c70d97880dfe8191b3 -
$ [ "$(cat foo)" == "$a" ] || echo false
false
发生了什么事?为什么这些不相等?
答案 0 :(得分:4)
您在测试中进行比较的变量$a
包含换行符,而$(cat file)
的结果则不包含,因为尾随换行符已从命令替换中删除。
可以使用set -x
:
[ "$(cat foo)" = "$a" ] || echo false
++ cat foo
+ '[' a = 'a
' ']'
+ echo false
答案 1 :(得分:4)
这是因为$( )
修剪尾随换行符。从bash reference manual(强调添加):
Bash通过在子shell环境中执行命令并使用命令的标准输出替换命令替换来执行扩展,删除任何尾随换行符。
您可以通过打印$(cat foo)
:
$ echo "'$a'"
'a
'
$ echo "'$(cat foo)'"
'a'
...请注意,对于$( )
,结束单引号与“a”在同一行上结束,这意味着在“a”之后没有换行符。此外,
$ [ "$(cat foo)" = "a" ] && echo true || echo false
true
请注意,这是与字符串“a”进行比较,后者不包含换行符;而不是变量$a
,它确实包含换行符。
答案 2 :(得分:2)
命令替换从文件内容中删除所有尾随换行符。
您可以这样做将文件数据读回变量:
a='a
'
# if you have BASH >= 4 then use
mapfile arr < foo
IFS=
b="${arr[*]}"
# or else read file content into a variable and append a new line after each read
# b=; while read -r; do b+="$REPLY"$'\n'; done < foo
# now compare
[[ $b == $a ]] && echo true || echo false
true
# or check content
declare -p a b
declare -- a="a
"
declare -- b="a
"
# using printf
printf 'a=%q;b=%q\n' "$a" "$b"
a=$'a\n';b=$'a\n'