为什么 >/dev/null 没有按预期工作?

Why does >/dev/null not work as expected?

我编写了以下 shell 脚本:

#! /bin/bash

# This script is designed to find hosts with MySQL installed

nmap -sT my_IP_address -p 3306 >/dev/null -oG MySQLscan

cat MySQLscan | grep open > MySQLscan2

cat MySQLscan2

根据脚本,nmap 的输出应该发送到 /dev/null。另一方面,最终输出应该写入我的密码中的 MySQLscan2 文件。

与我预期的不同,有两个文件写入了我的密码: MySQLscan:包含我预期在 MySQLscan2 中的扫描输出。 MySQLscan2: 此文件为空。

我的脚本有错误吗?我该如何解决这个问题?

今天早些时候,我设法 运行 脚本输出正确。我不确定我是否以某种方式更改了脚本。我查了一遍又一遍,还是找不到,怎么了...

我正在使用 Kali Linux 和 Oracle VM Virtual Box。

> /dev/null 导致 shell 重定向标准输出,这是一个 文件 文件描述符为 1 在命令开始之前 /dev/null 换句话说就是丢弃 它。当 nmap 运行s 带有 -oG MySQLscan 选项时,它会打开一个新文件并 获取一个新的文件描述符。你可以用strace查看:

$ strace -f nmap -sT localhost -p 3306  -oG MySQLscan |& grep MySQLscan
execve("/usr/bin/nmap", ["nmap", "-sT", "localhost", "-p", "22", "-oG", "MySQLscan"], 0x7ffc88805198 /* 60 vars */) = 0
openat(AT_FDCWD, "MySQLscan", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 4

在此示例中 openat() 返回 4 作为新文件描述符(您 可以通过 man 2 openat 阅读有关此功能的更多信息)。自档案 描述符 4 在命令启动 MySQLscan 之前没有被重定向 被创建。另请注意,即使 openat() 的文件描述符 returns 打开 MySQLscan 被重定向到 /dev/null:

nmap -sT localhost -p 22  -oG MySQLscan 4>/dev/null

它不会阻止创建 MySQLscan,因为 openat() 每次从内核请求一个新的未使用的文件描述符 运行.