开始使用时 echo -n 命令的有趣行为

Posted

技术标签:

【中文标题】开始使用时 echo -n 命令的有趣行为【英文标题】:Interesting behaviour of echo -n command when used in the beginning 【发布时间】:2020-06-21 21:16:39 【问题描述】:

我看到一些命令的有趣行为,当使用 echo -n 命令进行管道传输时需要手动中断。

bash-3.2$ openssl
OpenSSL> exit

bash-3.2$ echo -n | openssl
OpenSSL> bash-3.2$

bash-3.2$ telnet 10.207.139.8 22
Trying 10.207.139.8...
Connected to 10.207.139.8.
Escape character is '^]'.
SSH-2.0-OpenSSH_7.4
^]
telnet> Connection closed.

bash-3.2$ echo -n | telnet 10.207.139.8 22
Trying 10.207.139.8...
Connected to 10.207.139.8.
Escape character is '^]'.
Connection closed by foreign host.
bash-3.2$

当与 echo -n 一起使用时,它不会提示用户输入。幕后发生了什么?

echo 命令的手册页是这样说的

 -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.

【问题讨论】:

【参考方案1】:

当您将两个命令连接到管道foo | bar 时,第一个命令的输出将作为输入传递给第二个命令。

相比之下,当您只运行第二个命令bar 时,它的输入是从环境继承的。在您的情况下,这意味着输入来自您在控制台上输入。

所以,这个:

openssl

运行 openssl 并让您输入输入,而这个:

echo -n | openssl

以完全空的输入运行 openssl — 因此它会立即看到文件结尾并退出。

(在许多情况下,程序仍然可能访问控制台并直接与您交互。但通常 Unix-y 程序不会以这种方式强迫自己。如果您将标准输入重定向到其他地方,大多数 Unix-y 程序都会尊重这一点。)

顺便说一句,将空输入传递给命令的更传统方法是使用特殊的始终为空的文件/dev/null

openssl </dev/null

【讨论】:

以上是关于开始使用时 echo -n 命令的有趣行为的主要内容,如果未能解决你的问题,请参考以下文章

bash脚本和zsh shell中的数组行为(开始索引0或1?)

Python 函数 - 字典作为输入 - 返回错误 - 有趣的行为

使用 CUDA 4.2 和驱动程序 295.41 的非常有趣的行为

配置sudo命令行为审计

有趣的 LinqToSql 行为

基准测试期间有趣的 MySQL 行为