无法通过 ssh 运行命令

无法通过 ssh 运行命令

我在 FreeBSD 机器 (xxx.yyy.zzz.net) 上运行命令并获取输出

命令

sudo camcontrol devlist | grep -o 'ada[0-9]' | while read -r a ; do sudo camcontrol identify $a | grep rotating ; done

输出

media RPM             non-rotating
media RPM             non-rotating
media RPM             non-rotating

我正在尝试从另一台机器使用 ssh 运行相同的命令

命令

ssh xxx.yyy.zzz.net sudo camcontrol devlist | grep -o 'ada[0-9]' | while read -r a ; do sudo camcontrol identify $a | grep rotating ; done

错误

sudo: camcontrol: command not found

答案1

在您的命令中,每个命令|都由您的本地 shell 解释。最后一个参数sshdevlistssh在本地调用(这并不奇怪),但第一个 之后的所有内容也是如此|

您收到的错误来自sudo此代码片段:do sudo camcontrol identify $a。它在本地运行,显然camcontrol在本地机器上不可用。

您需要正确转义或引用。在这种情况下,您可能需要将整个远程命令括在单引号中:

ssh xxx.yyy.zzz.net 'sudo camcontrol devlist | grep -o "ada[0-9]" | while read -r a ; do sudo camcontrol identify $a | grep rotating ; done'

注意我更改了您已有的单引号。(添加的)单引号不仅将整个字符串分组以便ssh获取它;它们还阻止了 的局部扩展$a

如果sudo要要求您输入密码,则需要伪终端。您可以使用-t选项强制分配伪终端ssh(因此看起来像ssh -t xxx.yyy.zzz.net …)。注意ssh -t在远程端分配伪终端。远程sudo提示到其 stderr,但 stdout 和 stderr 会被此伪终端“打印”(就像它们通常打印到控制台一样),此时您无法再区分它们;合并的流被捕获并传输到本地端,然后转到 stdout。如果没有-t远程 stdout 和 stderr 单独传输,则转到本地端的 stdout 和 stderr,它们最终会合并(如果重定向则不会)成您看到的内容。这意味着-t您无法(在本地端)区分远程 stderr 和远程 stdout。如果您需要进一步本地处理(重定向)输出并且您使用,-t那么任何来自的提示sudo都会干扰。

此外,您可能还想使用双引号$a(即使在第一个不使用的命令中ssh)。请参阅为什么我的 shell 脚本会因空格或其他特殊字符而阻塞?

相关内容