What is the preferred way to test if a command takes an option? What are the caveats?
As a motivating example, at login my shell aliases grep to add several --exclude-dir options but this option is not available on all the machines I access.
Fortunately, there is a relatively standardized way to report potential options to programs. However, it is not always used, so this is not a fool-proof answer; just a poweruser-proof answer.
$prog --help | grep -e "\b$option\b" (note, \b means word boundary. That is so there will be no characters left after your $option, so, $option-f will not match)
That will return you the option, if it exists - but more importantly, return an exit status of 0 if it exists, or an exit status of 1 if it does not. You can test this with:
$ # we pipe to /dev/null to hide the output, and show that it doesn't matter $ grep --help | grep -e "\b--exclude-dir\b" > /dev/null $ echo $? 0 $ grep --help | grep -e "\b--exclude-dirf\b" > /dev/null $ echo $? 1 This will work on many programs, but not all have a --help that is... helpful. You may have also have luck with
man $progr | grep -e "\b$option\b" if the first fails
\b around the $option, to avoid a false positive for --exclude-d? realpath program : realpath --foo="/tmp" "/tmp/bar" ; echo $? (I discovered this when using --relative-to option). You can do a test on dummy data which should succeed if and only if the option is available and working as expected:
trap 'if [ -e "$tmp" ]; then rm -rf -- "$tmp"; fi' EXIT tmp="$(mktemp -d)" cd -- "$tmp" mkdir exclude mkdir include echo foo > include/test.txt echo foo > exclude/test.txt [ "$(grep --exclude-dir exclude --recursive foo . | wc -l)" -eq 1 ] Given that most (all?) commands exit with return code greater than zero when called with unknown options, you can try
cmd --option-to-probe [other options and parameters] >/dev/null 2>/dev/null and check whether $? is 0 or not.
You could grep the man page of the command to see if the option is there, something like this:
CMD=grep OPTIONS="" for OPT in "--exclude-dir" "--text" "--not_an_option"; do if man $CMD | col -bx | egrep --quiet \\$OPT; then OPTIONS="$OPTIONS $OPT" fi done alias $CMD="$CMD $OPTIONS"