为什么 2 台 linux 机器在使用相同语法的命令时表现不同?

lam*_*988 4 shell bash find wildcards

我正在使用 2 台机器,它们都是Red Hat Enterprise Linux AS 版本 3(Taroon Update 2) (我在 /etc/*-release 中检查它)。

我检查了他们使用相同的默认 shell by ps -p $$,即 bash。

我尝试使用通配符模式执行查找命令: find path -name pattern -type f -ctime +3

并且模式包含 * 字符作为通配符。

第一台机器似乎扩展了通配符并导致错误:

find /home/primbat/testing -name sftp_bcs_report_*.log -type f -ctime +7
find: paths must precede expression
Run Code Online (Sandbox Code Playgroud)

并且我需要在 2 个分隔的 qoute 之间创建模式,例如:\"sftp_bcs_report_*.log\"set -f在脚本中使用以抑制通配符扩展。

在别的机器里面,就没有这个问题。你有什么主意吗?

Net*_*tch 11

默认情况下,如果文件与通配符匹配,shell 将展开通配符,但在不匹配的情况下保持未展开。例如,如果您运行touch /tmp/111; touch /tmp/11*此命令将在 /tmp/111 上创建并更新 mtime,但如果 /tmp 为空但您调用touch /tmp/11*您将在 /tmp 中获得名为“11*”的文件。

这是贝壳的一个相当奇怪的特性。有时,如果没有特殊的 hack 作为中间函数,就不可能进行适当的扩展。当前大多数 shell 为典型情况发明了特殊选项;例如,bash 中的“shopt -s failglob”拒绝它运行通配符匹配失败的任何命令。

一个应该依赖于 find 的通配符扩展,所以这样的模式应该被引用来反对 shell 中的扩展:

find /home/primbat/testing -name 'sftp_bcs_report_*.log' -type f -ctime +7
Run Code Online (Sandbox Code Playgroud)

(注意单引号)。对于零个或一个文件,它可以工作,但是对于两个或多个文件,您的命令语法会损坏并且它会抱怨 - 这就是同事Arcege 所说的。您的“set -f”完全禁用扩展 - 嗯,这是诊断的好方法,但可以为未来的移动提供水下耙子。报价更简单:)


Arc*_*ege 5

听起来第二台机器上的起始目录中没有匹配的文件sftp_bcs_report_*.log,而第一台服务器上有多个这样的文件。对于使用find,模式应始终被引用。