find * 在 Debian 上查找名为“*”的文件,但在 RHEL 上则不然

find * 在 Debian 上查找名为“*”的文件,但在 RHEL 上则不然

区别在哪里呢?这些发行版的处理方式是否有所不同?还是配置不同?我需要比较和调整什么?我不想find *匹配通配符本身。

  • 结果不同,因为一台主机*也匹配:与红帽主机,Debian主机*也搜索。但没有名为*.
  • 平台:Debian Wheezy 7、Red Hat Enterprise Linux 7。始终使用 Bash。
  • grep应该在/etc./etc/hostname每个主机只能有一场比赛:Debian主机等等cat /etc/sysconfig/network红帽主机
DebianHost# cat $(查找 /etc/ *) 2>/dev/null | grep $(主机名)
find: ‘*’: 没有这样的文件或目录
Debian主机
DebianHost#
DebianHost#
DebianHost#
DebianHost# 主机名
Debian主机
DebianHost#
DebianHost#
DebianHost#
DebianHost# pwd
/根
DebianHost#
DebianHost#
DebianHost#
DebianHost# ls -1 .
DebianHost#
DebianHost#
DebianHost#
DebianHost# grep -r $(主机名) /etc
/etc/主机名:DebianHost
DebianHost#
DebianHost#
DebianHost#
DebianHost# 查找 /etc/ * | grep -e “*”
find: ‘*’: 没有这样的文件或目录
DebianHost#

RedHatHost# cat $(查找 /etc/ *) 2>/dev/null | grep $(主机名)
主机名=RedHatHost
红帽主机#
红帽主机#
红帽主机#
RedHatHost# 主机名
红帽主机
红帽主机#
红帽主机#
红帽主机#  
RedHatHost# pwd
/根
红帽主机#
红帽主机#
红帽主机#
RedHatHost# ls -1 .
anaconda-ks.cfg
安装日志
安装.log.syslog
红帽主机#
红帽主机#
红帽主机#
RedHatHost# grep -r $(主机名) /etc/
/etc/sysconfig/network:HOSTNAME=RedHatHost
红帽主机#
红帽主机#
红帽主机#
红帽主机#
RedHatHost# 查找 /etc/ * | grep -e “*”
红帽主机#

答案1

在这*两种情况下, 都是由 shell 扩展的。您可能来自 Windows,其中 shell 永远不会扩展通配符,只是将它们逐字传递给程序。 Unix shell 不是这样工作的。

看到这一点的最好方法是echo *在两台机器上都说。在你的 Debian 机器上,它会打印,*因为你在一个没有文件的目录中运行它,所以它*会传递给程序。 (我假设您正在运行 Bash,当通配符与任何内容都不匹配时,它会将通配符传递给被调用的程序。)在您的 Red Hat 机器上,它会显示

anaconda-ks.cfg install.log install.log.syslog

也就是说,运行它的目录中的三个文件名被传递给echo打印出来,并用一个空格分隔其参数。

我不确定你想要使用 来达到什么效果find /etc/ *,因为这并不是一个真正明智的find命令。如果您只想列出/etc树中的所有文件,find /etc就足够了。

答案2

*包含非引号通配符(本身就是通配符),它被视为全局并扩大了通过外壳到与该模式匹配的文件列表。

该特定模式 ( *) 匹配任何非隐藏文件名,因此,在调用findshell 之前,会将其扩展到当前目录中的非隐藏文件列表,因此,如果当前目录包含一个名为 的文件foo和另一个名为 的文件foo bar,则它将find使用这些参数进行调用:

"find", "/etc/", "foo", "foo bar"

如果当前目录中没有非隐藏文件,则不同 shell 的行为会有所不同。csh, tcsh, fish,zsh将发出不匹配错误消息并且不运行命令,而 POSIX shell 仍会调用find但模式未展开。因此,在这些中,find将使用这些参数进行调用:

"find", "/etc/", "*"

(要求查找和 中find的所有文件(在本例中不存在))。最有可能的是,在 RedHat 上,您从包含非隐藏文件的目录调用该命令,而在 Debian 上,您从仅包含隐藏文件的目录调用该命令。/etc/*

顺便一提

cat $(find /etc/ *) 2>/dev/null | grep $(hostname)

是错的。

你应该这样写:

find /etc -type f -exec cat {} + | grep -Fe "$(hostname)"

或者可能更有用:

find /etc -type f -exec grep -Fe "$(hostname)" {} +

或者因为 Debian 和 RedHat 都有 GNU grep:

grep -rFe "$(hostname)" /etc

答案3

find /etc *不查找名为 的文件*。它的行为方式取决于当前目录是否为空。

  • 如果它是空的,那么壳就会扩展find /etc *到自身;find看到它被告知遍历两个目录/etc*,并抱怨*不存在(除了列出 下的所有文件之外/etc)。这就是您在 Debian 上看到的。
  • 如果不为空,则 shell 扩展find /etc *find /etc后跟当前目录中的文件列表。因此find列出了 下的所有文件/etc,以及当前目录下除当前目录本身之外的所有文件。这就是您在 RHEL 上看到的内容。

差异与分布无关,您在两台机器上的不同上下文中进行测试。

这些都与查找名为*.如果要按名称查找文件,则需要使用谓词-namefind /etc -name somename。的参数-name是一个通配符模式,就像 shell 中的通配符模式一样。由于该字符*是通配符,为了查找名为 的文件*,您需要使用反斜杠保护通配符:find -name '\*'。请注意引号的两个级别:单引号用于防止字符\*shell 扩展(您可以使用find -name "\\*"orfind -name \\\*代替),以便find看到模式\*,以及反斜杠,以便模式是“文字*”而不是“任何序列”字符”。

*是文件名中有效但不常见的字符。如果您实际上不想匹配名称为 的字符*,而是任何文件,那么您可以编写find /etc -name '*'(同样,您需要引用 ,*以便 shell 不会扩展它),但这与find /etc.

准确地说,当前目录是否包含点文件以外的文件,即是否包含名称不以..

相关内容