I was experimenting with shell functions the other day, with the objective of overriding the ls
command.
The intention was to have the shell call my ls
function first then if the first switch is "-y" do one thing, otherwise call the regular /bin/ls
, but the result behaves in a way I don't understand.
To enable it I decided to use "-y" for the switch because:
$ ls -y
ls: invalid option -- 'y'
Try `ls --help' for more information.
So it can't break the core functionality of ls
.
Anyway, reducing the problem to its simplest, and with a couple of other examples to help highlight the problem:
$ function ls() { [[ "y$1" == "y-y" ]] && echo LS ; }
$ function less() { [[ "y$1" == "y-y" ]] && echo LESS ; }
$ function try() { [[ "y$1" == "y-y" ]] && echo TRY ; }
So I'm overriding ls
, less
and defining try
which is like the "contol" specimen :)
Now Invoking this way:
$ ls ; less ; try
It behaves as expected (no output), but:
$ ls -y ; less -y ; try -y
LESS
TRY
the ls
fails to work, but the less
override does, as does the "control".
Elsewhere on stackoverflow or askubuntu (but I've lost the reference for the minute) I saw an example that implied ls
was a builltin, but:
$ which ls
/bin/ls
and:
$ builtin ls
bash: builtin: ls: not a shell builtin
So it doesn't seem to be on my system (and even if it was I can't actually see why it would behave like this).
I wonder what the explanation is? It isn't important, but I'd like to understand what's going on.
Thanks.
Don't use which
, use type
. If you have something like
$ type ls
ls is aliased to `ls --color=auto'
Then your function will fail in an interactive shell. Remove this in your .bashrc
or wherever its defined. You can also use the unalias
builtin.
You also need to avoid recursion if running a command of the same name as a function within a function.
ls()
if [[ $1 == -y ]]; then
shift
...
else
command ls "$@"
fi
Also, make sure you know what you're doing if you decide to define functions using the function
keyword. Use POSIX-style funcname() compound-command
when you need POSIX compatibility as of this writing.