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

标签 bash shell openssl echo telnet

我发现一些命令有一个有趣的行为,当使用 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.

最佳答案

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

相比之下,当您单独运行第二个命令 bar 时,它的输入是从环境继承的。就您而言,这意味着输入来自您在控制台上键入的内容。

所以,这个:

openssl

运行openssl并让您向其中键入输入,而:

echo -n | openssl

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

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

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

openssl </dev/null

关于bash - 开始时使用 echo -n 命令的有趣行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60609763/

相关文章:

c# - OpenSSL 代码 native 工作,但作为 DLL 导致 OPENSSL_Uplink : no OPENSSL_Applink

arrays - Bash 脚本和数组推送

bash - shell $RANDOM 种子在管道中不被接受

bash - 从文件中删除所有以 # 开头的行

bash - 如何在bash脚本中用\t替换或转义<tab>字符并能够输出单引号?

linux - shell脚本中字符串变量中的特殊字符

linux - 从文件中获取信息shell脚本linux grep命令

bash - ls $FOLDER_PATH $FOLDER_PATH : No such file or directory 中有空格

authentication - OpenSSL 是否有 GMAC API 和示例

openssl - 如何使用 PKCS5_PBKDF2_HMAC_SHA1()