为什么对某些 netstat 命令使用 grep 需要 sudo priv?

为什么对某些 netstat 命令使用 grep 需要 sudo priv?

系统:

  • Ubuntu 20.04.06
  • 网络工具 2.10-alpha
  • grep (GNU grep) 3.4

如果我在没有 sudo 的情况下运行 netstat,我会看到端口信息,但看不到进程信息。这是预期的,因为进程信息需要提升的权限。

$ netstat -tulpn
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 127.0.0.53:53           0.0.0.0:*               LISTEN      -
tcp        0      0 127.0.0.1:43445         0.0.0.0:*               LISTEN      -
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      -
tcp        0      0 0.0.0.0:25              0.0.0.0:*               LISTEN      -
tcp        0      0 0.0.0.0:111             0.0.0.0:*               LISTEN      -
tcp        0      0 127.0.0.1:41933         0.0.0.0:*               LISTEN      -
tcp        0      0 0.0.0.0:443             0.0.0.0:*               LISTEN      -
tcp        0      0 127.0.0.1:42649         0.0.0.0:*               LISTEN      -
tcp        0      0 127.0.0.1:46059         0.0.0.0:*               LISTEN      -
tcp        0      0 127.0.0.1:45983         0.0.0.0:*               LISTEN      -
tcp        0      0 0.0.0.0:5001            0.0.0.0:*               LISTEN      -
tcp        0      0 0.0.0.0:5433            0.0.0.0:*               LISTEN      -
tcp        0      0 0.0.0.0:5432            0.0.0.0:*               LISTEN      -
tcp        0      0 127.0.0.1:34903         0.0.0.0:*               LISTEN      -
tcp        0      0 127.0.0.1:631           0.0.0.0:*               LISTEN      -
tcp        0      0 127.0.0.1:37257         0.0.0.0:*               LISTEN      -
tcp        0      0 127.0.0.1:37081         0.0.0.0:*               LISTEN      -
tcp        0      0 127.0.0.1:38445         0.0.0.0:*               LISTEN      -
tcp        0      0 127.0.0.1:38335         0.0.0.0:*               LISTEN      -
tcp6       0      0 ::1:3350                :::*                    LISTEN      -
tcp6       0      0 ::1:631                 :::*                    LISTEN      -
tcp6       0      0 :::2377                 :::*                    LISTEN      -
tcp6       0      0 :::3389                 :::*                    LISTEN      -
tcp6       0      0 :::22                   :::*                    LISTEN      -
tcp6       0      0 :::25                   :::*                    LISTEN      -
tcp6       0      0 :::111                  :::*                    LISTEN      -
tcp6       0      0 :::443                  :::*                    LISTEN      -
tcp6       0      0 :::7946                 :::*                    LISTEN      -
tcp6       0      0 :::5001                 :::*                    LISTEN      -
tcp6       0      0 :::5433                 :::*                    LISTEN      -
tcp6       0      0 :::5432                 :::*                    LISTEN      -
udp        0      0 127.0.0.53:53           0.0.0.0:*                           -
udp        0      0 0.0.0.0:111             0.0.0.0:*                           -
udp        0      0 0.0.0.0:631             0.0.0.0:*                           -
udp        0      0 0.0.0.0:4789            0.0.0.0:*                           -
udp        0      0 0.0.0.0:5353            0.0.0.0:*                           -
udp        0      0 0.0.0.0:43294           0.0.0.0:*                           -
udp6       0      0 :::52206                :::*                                -
udp6       0      0 :::111                  :::*                                -
udp6       0      0 :::5353                 :::*                                -
udp6       0      0 :::7946                 :::*                                -

但是,如果我尝试将该输出发送到 grep,则会收到一条错误消息,提示我需要 sudo priv。为什么?标准输出上没有显示任何进程信息,为什么 grep 会改变这一点?

$ netstat -tulpn | grep 8080
(Not all processes could be identified, non-owned process info
 will not be shown, you would have to be root to see it all.)

故障排除:

  • -p如果我不包括(即netstat -tuln | grep 8080),则不会发生这种情况
  • netstat -tulpn | grep 8如果我使用较小的 grep 字符串(即),则不会发生这种情况
  • 使用ss不会显示相同的问题(即ss -tulpn | grep 8080

这里发生了什么?

注意:是的,我知道 netstat 已被弃用,我应该使用ss它,我只是好奇为什么会发生这种行为。

答案1

您很可能总是收到此消息,但是什么时候您收到消息更改。

该消息正在绕过 grep 发送到 stderr。因此,当您看到它时,会存在一些竞争条件。

netstat 可能会在选项解析之后立即打印它,然后再打印任何数据。如果 grep 立即开始打印数据,该消息将与其他输出混合在一起,您可能会错过它,或者它最终可能会被打印出来。如果 grep 需要一些时间,那么该消息可能会显示在输出的开头。

如果没有管道引起的缓冲和随机延迟,消息应该始终位于开头。

如果您想忽略该消息,可以尝试

netstat -tulpn 2> /dev/null | grep 8080

如果您希望消息始终由 grep 过滤,您可以尝试(对于像 bash 这样的较新 shell)

netstat -tulpn /dev/null |& grep 8080

或等效的(对于所有 shell)

netstat -tulpn 2&>1 | grep 8080

请注意,如果将原始命令通过管道传输到分页器,则 stderr 输出也将绕过分页器,并且可能会短暂看到,但分页器几乎可以保证打印它和/或擦除它。

答案2

正如您所指出的,netstat需要以 root 身份运行才能显示某些信息。grep不需要特殊权限即可从管道中读取数据。所以,

sudo netstat -tulpn | grep 8080

如果没有 root 权限,-p当指示显示不属于您的进程的详细信息时,该标志将始终触发警告。也许您错过了看到该消息(特别是如果您将结果通过管道传输grep到分页器中,例如less将输出控制为全屏并且不处理写入的消息标准错误)。

相关内容