Question

If I want to match a file called "-f" or "-r" I might do something like

test.sh -?

And if I want to send the literal '-?' to a program as an argument I might do something like:

test.sh -\?

If no such file "-f" or "-r" or anything like it exists, then what should my shell do with

test.sh -?

Should it tell me that no file matches this pattern?

Was it helpful?

Solution

In bash, the default is to treat an unmatched pattern literally. If the nullglob option is set, an unmatched pattern "evaporates"; it is removed from command, not even expanding to the empty string.

In zsh, an unmatched pattern produces an error by default. Setting the nomatch option causes an unmatched pattern to be treated literally, and zsh also supports a nullglob option which causes unmatched patterns to disappear. There is also a cshnullglob option which acts like nullglob, but requires at least one pattern in a command to match, or an error is produced.

Note that POSIX specifies that if the pattern contains an invalid bracket expression or does not match any existing filenames or pathnames, the pattern string shall be left unchanged in sh.

ash, dash, ksh, bash and zsh all behave this way when invoked as sh.

OTHER TIPS

You seem to be looking for the nullglob option, at least with Bash:

shopt -s nullglob

Without the nullglob option, an unmatched pattern is passed as its literal self to your program: the shell will pass -? to the script if there isn't a file that matches. With the nullglob option, unmatched patterns are replaced with nothing at all.

If no such pattern exists, the shell, by default, just returns the pattern your gave, including whatever * or ? characters you used. To determine whether the file actually exists, test it. Thus, inside your script, use:

[ -f "$1" ] ||  echo "no such file exists"
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top