使用 ssh 如何使用远程检查我的服务器上是否安装了 python3 或任何其他给定的包?

使用 ssh 如何使用远程检查我的服务器上是否安装了 python3 或任何其他给定的包?

我有一台 Ubuntu 服务器,上面已经设置了 ssh 密钥。无需登录,我想从本地计算机上运行的 bash 脚本检查服务器上是否已安装给定的软件包。所需的输出是布尔值 0 或 1。到目前为止,我想出的命令是:

$ ssh root@myserver 'dpkg-query -W python3 | grep -c "no package found"'
0

此命令对于已安装的包和未安装的包均输出 0。

我退后一步,尝试在本地机器上实现这一点。发生了一些对我来说很奇怪的事情。

当我尝试时:

$ dpkg-query -W python
dpkg-query: no packages found matching python

当我尝试时:

$ dpkg-query -W python3
Desired=Unknown/Install/Remove/Purge/Hold
| Status=Not/Inst/Conf-files/Unpacked/halF-conf/Half-inst/trig-aWait/Trig-pend
|/ Err?=(none)/Reinst-required (Status,Err: uppercase=bad)
||/ Name           Version        Architecture Description
+++-==============-==============-============-=========================================================================
ii  python3        3.8.2-0ubuntu2 amd64        interactive high-level object-oriented language (default python3 version)

这很好,因此对于“python”的情况,我希望将此输出通过管道传输到 grep 并检查其中是否存在类似“未找到包”的字符串。我运行以下命令,令人惊讶的是返回了 0。

$ dpkg-query -W python | grep -c "no packages found"
dpkg-query: no packages found matching python
0

这不应该返回单行 1 吗?为什么我已将其通过管道传输到另一个命令,但命令输出仍显示在终端上?我假设输出从未通过管道传输到 grep,因为我可以成功运行:

$ echo "dpkg-query: no packages found matching python" | grep -c "no packages found"
1

请解释为什么会发生这种情况,如果我因为困惑而问了一个琐碎的问题,请原谅我。

答案1

这是一条非常普遍的规则:命令的错误消息写入 stderr,而不是 stdout。管道仅将 stdout 重定向到另一个命令;stderr 仍与终端保持连接。dpkg-query: no packages found matching python是一条错误消息,因此将其写入 stderr(即终端),并将 stdout 上的空输出通过管道传输到grep,因此grep返回 0。

如果你希望 stdout 和 stderr 都通过管道传输grep,你应该使用类似

dpkg-query -W python 2>&1 | grep -c "no packages found"

您在问题中包含的命令的 ssh 版本也将不是按照您描述的方式工作。您还应该2>&1像上面的命令一样在其中包含,否则它将完全按照本地版本工作 - 除非您的 ssh 客户端(或远程计算机上的服务器)以某种方式配置为将 stderr 重定向到 stdout,但这是不是标准配置。在我的例子中,ssh 版本的行为与本地版本完全相同。

dpkg-query但是,您不必通过管道传输through的输出grep(这可能依赖于语言环境,因此不可靠),而是只需使用命令的返回代码即可dpkg-query。如果包已安装,则返回代码为 0,否则为 1。因此,您可以使用类似

dpkg-query -W python >& /dev/null ; echo $?

>& /dev/null是否能从dpkg-query(stdout 和 stderr) 中删除任何输出,因为我们只对返回代码感兴趣 ( $?)。注意:>&在 中有效bash。如果您希望在 (例如在脚本中) 中使用它sh,则应改用此方法:

dpkg-query -W python >/dev/null 2>&1 ; echo $?

相关内容