Bash – Why 2 linux machine behave differently with command of the same syntax

bashfindshellwildcards

I am using 2 machine , which is both Red Hat Enterprise Linux AS release 3 (Taroon Update 2)
( I check it in /etc/*-release ).

I checked they are using the same default shell by ps -p $$, which is bash.

I tried to execute a find command with wildcard pattern:
find path -name pattern -type f -ctime +3

and the pattern contain * character as wildcard.

The first machine seems to expanded the wildcard character and causing error:

find /home/primbat/testing -name sftp_bcs_report_*.log -type f -ctime +7
find: paths must precede expression

and I need to either make the pattern in between 2 delimited qoute, e.g: \"sftp_bcs_report_*.log\" or using set -f in the script to suppress wildcard expansion.

Which in the other machine, it have no such problem. Do you have any idea?

Best Answer

By default, shells expand wildcards if a file matches them but keep unexpanded without match. For example, if you run touch /tmp/111; touch /tmp/11* this will create and then update mtime on /tmp/111, but if /tmp is empty but you call touch /tmp/11* you will get file named "11*" in /tmp.

This is rather weird feature of shells. Sometimes proper expanding isn't possible without special hacks as intermediate function. Most current shells invent special options for typical cases; e.g. "shopt -s failglob" in bash rejects it from running any command where wildcard match fails.

One shall rely on find's wildcard expanding, so such pattern shall be quoted against expansion in shell:

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

(note single quotes). With zero or one file, it works, but with two or more files you get broken command syntax and it complains - this is what is said by colleague Arcege. Your "set -f" disables expansion totally - well, it is good measure for diagnostics but can give underwater rakes for a future moving. Quotes are simpler:)

Related Question