在 bash 中测试 "tail -c 1"
Testing "tail -c 1" in bash
在中,一些帖子使用[[ ]]
和==
来比较字符。
我想写一个单行命令来检测EOF处是否没有换行,我遇到了这个小问题。
在echo
的输出中,最后有\n
。
$ echo echo | od -c
0000000 e c h o \n
0000005
$ echo -n echo | od -c
0000000 e c h o
0000004
如果我将 [[ ]]
和 ==
放在一起,那么我不会得到预期的输出。
$ [[ `echo echo | tail -c1` == "\n" ]] && echo true
$ [[ `echo echo | tail -c1` != "\n" ]] && echo true
true
$ [[ `echo -n echo | tail -c1` != "\n" ]] && echo true
true
如od -c
所示,echo echo | tail -c1
的输出是\n
,而[[ "\n" == "\n" ]] && true
会returntrue
,所以我预计第一个命令给出 true
。但是,为什么它被评估为空字符串?
感谢阅读!
正如Bash Reference Manual中明确指出的那样:
Bash performs the expansion by executing command in a subshell environment and replacing the command substitution with the standard output of the command, with any trailing newlines deleted.
打开-x
标志,看看会发生什么:
$ set -x
$ [[ `echo echo | tail -c 1` == '\n' ]]
++ tail -c 1
++ echo echo
+ [[ '' == \\n ]]
$
$ echo "$(echo)"
++ echo
+ echo ''
作为旁注,即使尾随的换行符没有被修剪,你的比较也不会 return 正确,因为 '\n'
不是换行符,而是字面上的反斜杠后跟字母n
。您应该使用 $'\n'
来获得实际的换行。
至于解决方案,您可以使用以下方法:
$ printf 'test\n' | perl -0777ne'exit(/\n\z/?0:1)' || echo "Missing line feed" >&2
$ printf 'test' | perl -0777ne'exit(/\n\z/?0:1)' || echo "Missing line feed" >&2
Missing line feed
或
$ printf 'test\n' | perl -0777ne'die("Missing line feed\n") if !/\n\z/'
$ printf 'test' | perl -0777ne'die("Missing line feed\n") if !/\n\z/'
Missing line feed
在[[ ]]
和==
来比较字符。
我想写一个单行命令来检测EOF处是否没有换行,我遇到了这个小问题。
在echo
的输出中,最后有\n
。
$ echo echo | od -c
0000000 e c h o \n
0000005
$ echo -n echo | od -c
0000000 e c h o
0000004
如果我将 [[ ]]
和 ==
放在一起,那么我不会得到预期的输出。
$ [[ `echo echo | tail -c1` == "\n" ]] && echo true
$ [[ `echo echo | tail -c1` != "\n" ]] && echo true
true
$ [[ `echo -n echo | tail -c1` != "\n" ]] && echo true
true
如od -c
所示,echo echo | tail -c1
的输出是\n
,而[[ "\n" == "\n" ]] && true
会returntrue
,所以我预计第一个命令给出 true
。但是,为什么它被评估为空字符串?
感谢阅读!
正如Bash Reference Manual中明确指出的那样:
Bash performs the expansion by executing command in a subshell environment and replacing the command substitution with the standard output of the command, with any trailing newlines deleted.
打开-x
标志,看看会发生什么:
$ set -x
$ [[ `echo echo | tail -c 1` == '\n' ]]
++ tail -c 1
++ echo echo
+ [[ '' == \\n ]]
$
$ echo "$(echo)"
++ echo
+ echo ''
作为旁注,即使尾随的换行符没有被修剪,你的比较也不会 return 正确,因为 '\n'
不是换行符,而是字面上的反斜杠后跟字母n
。您应该使用 $'\n'
来获得实际的换行。
至于解决方案,您可以使用以下方法:
$ printf 'test\n' | perl -0777ne'exit(/\n\z/?0:1)' || echo "Missing line feed" >&2
$ printf 'test' | perl -0777ne'exit(/\n\z/?0:1)' || echo "Missing line feed" >&2
Missing line feed
或
$ printf 'test\n' | perl -0777ne'die("Missing line feed\n") if !/\n\z/'
$ printf 'test' | perl -0777ne'die("Missing line feed\n") if !/\n\z/'
Missing line feed