为什么 2 台 Linux 机器使用相同语法的命令会有不同的行为?

为什么 2 台 Linux 机器使用相同语法的命令会有不同的行为?

我用的是2台机器,都是红帽企业 Linux AS 第 3 版(Taroon 更新 2) (我在 /etc/*-release 中检查它)。

我检查过他们使用的是相同的默认 shell 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

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

而在其他机器上则没有这样的问题。你有什么主意吗?

答案1

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

这是贝壳相当奇怪的功能。有时,如果没有特殊的黑客作为中间函数,正确的扩展是不可能的。大多数当前的 shell 都为典型情况发明了特殊选项;例如,bash 中的“shopt -s failureglob”会拒绝运行任何通配符匹配失败的命令。

需要依赖find的通配符扩展,因此在shell中应该引用这样的模式来防止扩展:

find /home/primbat/testing -name 'sftp_bcs_report_*.log' -type f -ctime +7

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

答案2

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

相关内容