The existing answer doesn't correctly handle commands with spaces -- and indeed cannot: Condensing an array into a string is inherently buggy.
This version works with the list of arguments as an array, and thus avoids this loss of information:
ls() {
local -a args=( )
for arg; do
[[ $arg = --color ]] || args+=( "$arg" )
done
command ls "${args[@]}"
}
Alternately, if your real goal is to alias a subcommand (and you might want to process more subcommands in the future), consider a case
structure, as the following:
ls() {
local subcommand
if (( "$#" == 0 )); then command ls; return; fi
subcommand=$1; shift
case $subcommand in
--color) command ls "$@" ;;
*) command ls "$subcommand" "$@" ;;
esac
}
Some tests, to distinguish correctness between this answer and the preexisting one:
tempdir=/tmp/ls-alias-test
mkdir -p "$dir"/'hello world' "$dir"/my--color--test
# with the alternate answer, this fails because it tries to run:
# ls /tmp/ls-alias-test/hello world
# (without the quotes preserved)
ls --color "$dir/hello world"
# with the alternate answer, this fails because it tries to run:
# ls /tmp/ls-alias-test/my--test
ls --color "$dir/my--color--test"