2

How do I expand an alias defined when using zsh -c?

% zsh -c 'setopt aliases complete_aliases; alias d=date; d'
zsh:1: command not found: d
Tom Hale
  • 40,825
  • 36
  • 187
  • 242

1 Answers1

4

Use eval to force the zsh to parse the alias after the code has been read in:

zsh -c 'setopt aliases complete_aliases; alias d=date; eval d'

In this case, d will never expand, so doesn't need to be quoted.

In general you should properly quote all arguments to eval.


man zshmisc says:

   There is a commonly encountered problem with aliases illustrated by the
   following code:

        alias echobar='echo bar'; echobar

   This prints a message that the command echobar could not be found.
   This happens because aliases are expanded when the code is read in; the
   entire line is read in one go, so that when echobar is executed it is
   too late to expand the newly defined alias.  This is often a problem in
   shell scripts, functions, and code executed with `source' or `.'.
   Consequently, use of functions rather than aliases is recommended in
   non-interactive code.
Tom Hale
  • 40,825
  • 36
  • 187
  • 242
  • Better yet, don't use an alias; define a function. A function definition is an ordinary command, and so is guaranteed to be defined before you attempt to use it, even on the same command line. `zsh -c 'd() date; d`. – chepner Feb 25 '19 at 16:02
  • 2
    @chepner Generally good advice, but in this case I'm writing a generic alias expander for use in `nohup alias`, `nice alias`, `chrt alias` etc. – Tom Hale Feb 26 '19 at 13:09
  • 2
    Had to scour the internet to find this answer, so THANK YOU! As of 2022, it seems this can be reduced to `zsh -c 'alias d=date; eval d'`. – Xunnamius Apr 01 '22 at 06:07
  • 1
    Another thank you from 2022! In my case I'm trying to use `viddy` (which is just like `watch`) and to watch the output of a shell alias defined in my ~/.zshrc. For this to work in viddy this does the trick: `viddy --shell zsh "source ~/.zshrc; eval ll"` (with the alias `ll` in that case). You'd think I could do `zsh --interactive` but that causes the shell to exit weirdly for reasons I don't yet grasp. – Chris Jul 22 '22 at 01:18
  • big thanks from me as well, spared me from fake interactive shell damnation – Guido Tarsia Sep 26 '22 at 02:06