ZSH Gem #11: Path and filename expansion
Yesterday I told you about Backtick expansion. Today I want to show you one more interesting expansion feature and that is path expansion for executable files.
I suppose you're familiar with the which
command. With that command you can find out where an executable is located. So for example if you want to know which executable on the hard disk is called when you invoke the command cp
you'd run:
which cp
and it would give you the name to the executable file (usually /bin/cp
). For just looking up a path name you'd often prefer which
over what I show you next simply because it can do some more stuff such as showing all occurrences in $PATH
of this executable with the parameter -a
. But the following ZSH feature isn't really meant to replace which
.
Provided the EQUALS
option is set (which is by default), each unquoted occurrence of =
followed by one or more characters is treated as a command name. You can check that easily:
% =mv<TAB>
With the TAB key the expression =mv
gets expanded to /bin/mv
. The reason why I don't use the cp
example from above is because the TAB completion of equal sign expressions doesn't work when the expression may be ambiguous. So if expansion of =mv
doesn't work on your system and you get a list of executables starting with mv
, you know why. But that is not the point. It is often not very expedient to use this kind command line expansion here (at least I can't think of any use for this).
However, you can use the equal sign operator like any other operator such as backticks. Those can be expanded with TAB as well but you don't have to. The same applies to =
expressions. For instance:
myparam==cp
The double equal sign is not a mistake. The first one is the normal assignment operator for shell variables, the second one the expansion operator. When you now run echo $myparam
you won't get =cp as you might expect but /bin/cp.
You can use that anywhere. If you like typing more characters than needed, you can even start writing all your commands with an equal sign:
=ls dir
would be expanded to
/bin/ls dir
before it's executed (though you won't notice it).
Such a path expansion is sometimes helpful when you need absolute paths (e.g. you need to pass the path of an executable to another program). But of course you can also use it as a shorthand for which
as I showed you above (at least as long as you don't need any of the more advanced features of which
). With TAB completion directly on the command line it might be a little cumbersome which
replacement, but in shell scripts you could definitely use it.
listcmd==ls
is definitely shorter than
listcmd=$(which ls)
although it might confuse others which are not so familiar with the ZSH syntax.
A similar expansion syntax also exists for directories. Instead of =
you'd use ~
here,. I won't explain it here because that's a relatively complex topic. Let me just show you two little things: the one is an expansion expression for the current working directory (i.e. a shorthand for $PWD
or `pwd`
) and the second for the former working directory. They are ~+
and ~-
. Other operators would be for handling the directory stack (you might know that feature from Bash and if not, follow the link below this article) or static named directories such as the home directories.
Read more about path and filename expansion: