As an addition to Romeo's answer, note that
grep pattern --whatever
is required by POSIX to look for pattern in the
--whatever file. That's because no options should be recognised after non-option arguments (here
grep in that instance is not POSIX compliant. It can be made compliant by passing the POSIXLY_CORRECT environment variable (with any value) into its environment.
That's the case of most GNU utilities and utilities using a GNU or compatible implementation of
getopt_long() to parse command-line arguments.
There are obvious exceptions like
env VAR=x grep --version gets you the version of
env. Another notable exception is the GNU shell (
bash) where neither the interpreter nor any of its builtins accept options after non-option arguments. Even its
getopts cannot parse options the GNU way.
Anyway, POSIXLY_CORRECT won't save you if you do
grep -e pattern *.js
pattern is not a non-option argument, it is passed as an argument to the
-e option, so more options are allowed after that).
So it's always a good idea to mark the end of options with -- when you can't guarantee that what comes after won't start with a
+ with some tools):
grep -e pattern -- *.js
grep -- pattern *.js
grep -e pattern ./*.js
grep -- pattern * won't help you if there's a file called
grep pattern ./* would work.
grep -e "$pattern" should be used instead of
grep "$pattern" in case
$pattern itself may start with
There was an attempt in the mid-90s to have
bash be able to tell
getopt() which arguments (typically the ones resulting from a glob expansion) were not to be treated as options (via a
_<pid>_GNU_nonoption_argv_flags_ environment variable), but that was removed as it was causing more problems than it solved.