“echo”和“echo -n”有什么区别?

22

关于使用echo -n命令的终端手册页面如下:

 -n    Do not print the trailing newline character.  This may also be
       achieved by appending `\c' to the end of the string, as is done by
       iBCS2 compatible systems.  Note that this option as well as the
       effect of `\c' are implementation-defined in IEEE Std 1003.1-2001
       (``POSIX.1'') as amended by Cor. 1-2002.  Applications aiming for
       maximum portability are strongly encouraged to use printf(1) to
       suppress the newline character.

 Some shells may provide a builtin echo command which is similar or iden-
 tical to this utility.  Most notably, the builtin echo in sh(1) does not
 accept the -n option.  Consult the builtin(1) manual page.

当我尝试生成MD5哈希时:

echo "password" | md5

它返回286755fad04869ca523320acce0dc6a4

当我执行:

echo -n "password"

它返回在线MD5生成器返回的值:5f4dcc3b5aa765d61d8327deb882cf99

选项-n有何区别?我不理解终端中的条目。


你可能会发现阅读echo的POSIX规范在http://pubs.opengroup.org/onlinepubs/009604599/utilities/echo.html也是值得的。值得注意的是,它指出`echo -n在所有UNIX系统上都**不可移植**(尽管这比echo -e`更好,后者无法实现而不违反标准!) - Charles Duffy
2个回答

15
当您执行echo "password" | md5时,echo会将一个新行添加到要进行哈希的字符串中,即password\n。当您添加-n开关时,它不会这样做,因此只有password字符被哈希。
最好使用printf,它可以按照您的要求执行而无需任何开关:
printf 'password' | md5

如果'password'不仅仅是一个字面字符串,你应该使用格式说明符:

printf '%s' "$pass" | md5

这意味着密码中的转义字符(例如\n\t)不会被printf解释,而是直接打印出来。

好的,现在更有意义了!我一直以为首先字符串被哈希,然后才添加换行符;现在我知道是相反的。 - user4820905
具有讽刺意味的是,现在我生成的哈希更难被破解,因为破解程序必须向每个条目添加一个换行符,所以在某种程度上使用 echo 更好! ;) - user4820905
你知道为什么在bash中比较字符串时会忽略换行符,就像这样:[[ $(echo -e "a\n") = $(echo -n "a") ]] && echo yes 为什么这个条件会返回true - Edgar Magallon
1
@EdgarMagallon 在命令替换中,所有尾随的换行符都会被删除,因此这些命令都等同于 a(在 shell 中运行 set -x 后自行尝试)。 - Tom Fenech
非常感谢!我之前不知道在使用命令替换时会出现这种行为。 - Edgar Magallon

6

echo 命令会自动添加一个新行,而 echo -n 则不会。

根据 man bash

echo [-neE] [arg ...]

输出参数,用空格分隔,后跟一个新行。 (...) 如果指定了 -n,则省略尾随的新行。

考虑到这一点,使用 printf 永远是更安全的选择,因为它提供与 echo -n 相同的功能。也就是说,不会自动添加默认的新行:

$ echo "password" | md5sum
286755fad04869ca523320acce0dc6a4  -
$ echo -n "password" | md5sum
5f4dcc3b5aa765d61d8327deb882cf99  -
$ printf "%s" "password" | md5sum
5f4dcc3b5aa765d61d8327deb882cf99  -   # same result as echo -n

查看为什么printf比echo更好?的精彩答案以获取更多信息。

另一个例子:

$ echo "hello" > a
$ cat a
hello
$ echo -n "hello" > a
$ cat a
hello$            # the new line is not present, so the prompt follows last line

我建议使用 printf %s "password",即使密码正在从变量中扩展并且可能包含反斜杠转义或类似内容,也可以可靠地工作。 - Charles Duffy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接