混淆“echo 命令 | ssh 服务器”和“ssh 服务器命令”

混淆“echo 命令 | ssh 服务器”和“ssh 服务器命令”

在学习非交互式登录 shell 的过程中,我遇到了两种通过 SSH 远程执行命令的方法。对我来说,它们看起来都是一样的。但不幸的是,事实并非如此。

使用命令echo "shopt login_shell; echo \$-" | ssh -l poweruser 192.168.1.67,我得到以下输出。

Pseudo-terminal will not be allocated because stdin is not a terminal.
[email protected]'s password:
login_shell     on 
hBs

但通过命令ssh -l poweruser 192.168.1.67 "shopt login_shell; echo \$-",我得到了不同的输出。

[email protected]'s password:
login_shell     off
hBc

您能否告诉我为什么在第二种情况下 shell 不是登录 shell,即使它提示输入密码。

答案1

man ssh文件表明:

如果一个命令指定后,它会在远程主机上执行,而不是在登录 shell 上执行。

原因是,在一种情况下您指定了一个命令,而在另一种情况下您没有指定,并且ssh故意(根据设计)在这些情况下表现不同。

在您没有提供命令的情况下,会启动一个登录 shell,它会读取管道输入并执行它。在您确实提供命令的那个中,它被启动了。

提示输入密码是无关的。这是在启动 shell 或命令之前向服务器验证您的身份。

答案2

这是不精确的,但它可能是一种有用的看待方式:

  • echo … | ssh …“看起来像”一个交互式会话—— ssh启动后从其标准输入读取 shell 命令。现在,当然,ssh 区分它的 stdin 是管道还是 tty(或文件),但它可能不会费心这样做。以不同于 tty 的方式处理管道可能会使使用类似的东西变得更加困难expect手册页)。

    echo … | ssh …感觉就像打电话给某人并要求他们做某事。有可能,您希望他们这样做立即地 (当您仍在打电话时),因此登录 shell 感觉更合适。

  • 使用,您可以指定在建立连接之前运行的命令。您不可能根据您看到的响应有条件地执行某些操作(除非出现问题时可能点击+ )。所以它不能是交互式的;这更像是ssh … commandsshCtrlC批量处理

    这感觉就像给某人发一封电子邮件并要求他们做某事。您不期望立即得到响应,因此登录 shell 感觉不太合适。

有关背景,请参阅为什么使用“登录”shell 而不是“非登录”shell? (其中——披露——唯一的答案是我写的)和 登录 Shell 和非登录 Shell 之间的区别?——尽管快速浏览了一下,我没有看到任何与这个问题直接相关的内容。

相关内容