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, usetype. If you have something likeThen your function will fail in an interactive shell. Remove this in your
.bashrcor wherever its defined. You can also use theunaliasbuiltin.You also need to avoid recursion if running a command of the same name as a function within a function.
Also, make sure you know what you’re doing if you decide to define functions using the
functionkeyword. Use POSIX-stylefuncname() compound-commandwhen you need POSIX compatibility as of this writing.