6

I use zsh and would like to slightly extend the in-built cd function. I'd like that when I call cd, it changes directly and then lists the content of the directory.

function cd() {
    cd $1
    ls .
}

I'd have expected this code to work, but as it turns out, the call to cd refers to the function definition, resulting in an infinite loop.

Is there a work-around to solve this problem, apart from choosing a different name for my function?

UPDATE

Strangely enough, this worked

function cd() {
    `echo $1`
    ls .
}

No idea why.

SamAko
  • 3,485
  • 7
  • 41
  • 77

2 Answers2

8

In order to use builtin commands from within functions of the same name, or anywhere else for that matter, you can use the builtin precommand modifier:

function cd() {
    builtin cd $1
    ls .
}

builtin COMMAND tells zsh to use the builtin with the name COMMAND instead of a alias, function or external command of the same name. If such a builtin does not exist an error message will be printed.


For cases where you want to use an external command instead of an alias, builtin or function of the same name, you can use the command precommand modifier. For example:

command echo foobar

This will use the binary echo (most likely /bin/echo) instead of zsh's builtin echo.


Unlike with functions builtin and command are usually not necessary with aliases to prevent recursions. While it is possible to use an alias in an alias definition

% alias xx="echo x:"
% alias yy="xx y:"
% yy foobar
y: x: foobar

each alias name will only expanded once. On the second occurence the alias will not be expanded and a function, builtin or external command will be used.

% alias echo="echo echo:"
% echo foobar
echo: foobar
% alias xx="yy x:"
% alias yy="xx y:"
% xx foobar
zsh: command not found: xx

Of course, you can still use builtin or command in aliases, if you want to prevent the use of another alias, or if you want to use a builtin or external command specifically. For example:

alias echo="command echo"

With this the binary echo will be used instead of the builtin.

Adaephon
  • 16,929
  • 1
  • 54
  • 71
  • In bash, using `command cd` worked fine. When migrating to zsh I got a `command not found: cd` error. Solved thanks to this post by replacing `command cd` with `builtin cd` for zsh. – young_souvlaki Jan 03 '22 at 18:34
2

Why the echo command works is because you probably have the autocd option on. You can check this by typing setopt to get your list of options.

Then the echo-ing of the directory name and catching the output triggered the autocd and you went to that directory.

Henno Brandsma
  • 2,116
  • 11
  • 12