find in directory that starts with dash
If it is in a script you can always check for it. E.g. for bash, ksh or zsh:
if [[ "$DIR" = -* ]]; then find ./"$DIR"else find "$DIR"fi
In a more terse form (for bash, ksh93 or zsh):
find "${DIR/#-/./-}"
You can even do this with the parameters of a script, if they are all supposed to be directories:
find "${@/#-/./-}"
This may seem a bit cheap, but I actually recommend the readlink
workaround that you've figured out. According to the Unix standard,
The first argument that starts with a '-' (...) and all subsequent arguments shall be interpreted as an expression
so --
will indeed not work. thkala's solution may also work, but I find it less readable. It may be faster though, if you're doing a lot of find
invocations.
Here is a way that should work on all Unix-like systems, with no requirement on a specific shell or on a non-standard utility¹.
case $DIR in -*) DIR=./$DIR;;esacfind "$DIR" …
If you have a list of directories in your positional parameters and want to process them, it gets a little complicated. Here's a POSIX sh solution:
i=1while [ $i -le $# ]; do case $1 in -*) x=./$1;; *) x=$1;; esac set -- "$@" "$x" shift i=$(($i + 1))donefind "$@" …
Bourne shells and other pre-POSIX sh implementations lack arithmetic and set --
, so it's a little uglier.
i=1while [ $i -le $# ]; do x=$1 case $1 in -*) x=./$1;; esac set a "$@" "$x" shift shift i=`expr $i + 1`donefind "$@" …
¹ readlink -f
is available on GNU (Linux, Cygwin, etc.), NetBSD ≥4.0, OpenBSD ≥2.2, BusyBox. It is not available (unless you've installed GNU tools, and you've made sure they're in your PATH
) on Mac OS X (as of 10.6.4), HP-UX (as of 11.22), Solaris (as of OpenSolaris 200906), AIX (as of 7.1).