I find that I often do the following:

%> cd bla/bla
%> ls

I would like it that whenever I cd into a directory it automatically does an ls.

I fiddled with my .bashrc for a while, but couldn't figure out how to make it happen.

10 Answers 10

You can do this with a function:

$ cdls() { cd "$@" && ls; }

The && means 'cd to a directory, and if successful (e.g. the directory exists), run ls'. Using the && operator is better then using a semicolon ; operator in between the two commands, as with { cd "$@" ; ls; }. This second command will run ls regardless if the cd worked or not. If the cd failed, ls will print the contents of your current directory, which will be confusing for the user. As a best practice, use && and not ;.

$ cdls /var/log
CDIS.custom     fsck_hfs.log    monthly.out     system.log
$ pwd
/var/log

In general, it is a bad practice to rename a command which already exists, especially for a commonly called command like cd. Instead, create a new command with a different name. If you overwrite cd with a function or alias which is also named cd, what would happen when you enter a directory with 100,000 files? There are many utilities which use cd, and they may get confused by this unusual behavior. If you use a shared account (Such as root when you are working with other system administrators), it can be very dangerous to replace an existing command because the environment is different from what people expect.

  • That command really change directory? From bash's man page: "There is no mechanism for using arguments in the replacement text. If arguments are needed, a shell function should be used" – enzotib Sep 9 '11 at 18:58
  • @enzotib : Yes, this really does change directory, at least for me. I updated my answer to show the output of pwd. Not sure if this is a best practice, but it is commonly done. See tldp.org/LDP/abs/html/aliases.html for some examples. – Stefan Lasiewski Sep 9 '11 at 19:05
  • 2
    First: it does not work here. Second: in that page they use variables, not positional parameters. Third: ABS is a common source of bad practices. – enzotib Sep 9 '11 at 19:07
  • Ok fine, I added a function also. Maybe ABS is full of bad practices (Some people say this about shell scripting, in general), but at least they are advanced bad practices. – Stefan Lasiewski Sep 9 '11 at 19:10
  • 1
    The alias works for me on Snow Leopard but not on CentOS5 or CentOS6. I updated my answer to use a function only. No aliases. – Stefan Lasiewski Sep 10 '11 at 0:37

I have this in my .bashrc, and it works fine.

function cd {
    builtin cd "$@" && ls -F
    }

Earlier in my .bashrc I have: [ -z "$PS1" ] && return, and everything after that line only applies to interactive sessions, so this doesn't affect how cd behaves in scripts.

  • What exactly does [ -z "$PS1" ] && return do? – syntagma Jan 21 '15 at 14:34
  • 2
    [ -z "$PS1" ] checks if the $PS (interactive prompt variable) is "zero length" (-z). If it is zero length, this means it has not been set, so Bash must not be running in interactive mode. The && return part exits from sourcing .bashrc at this point, under these conditions. – frabjous Jan 21 '15 at 17:42
  • 1
    Another way to check for interactivity is to look for i in "$-": case "$-" in *i*) ;; *) return ;; esac. – Kusalananda Jan 9 '17 at 19:38
  • @Kusalananda & frabjous: Are there cases where one should be used instead of the other? – Swivel Sep 30 '17 at 19:14
  • 1
    @Swivel The PS1 variable may be unset or empty and the shell may still be interactive (but without a prompt). I would check $- to make sure. – Kusalananda Sep 30 '17 at 19:24

off-topic, since the question is tagged /bash, but as some questions are closed as duplicate of this one that don't mention bash:

With zsh:

chpwd() ls

The chpwd() function is called by zsh whenever the current directory changes (by way of cd, pushd, popd...). tcsh has a similar feature and is probably where zsh got it from.

The common solution of creating alias for cd command is not perfect because there are other commands which can change your current directory like popd or even running a script with cd command in it.

It is better to use $PROMPT_COMMAND Bash hook which executes a command before returning a prompt.

The command (a function in our case) will execute ls only if directory has changed to reduce screen noise. Code for .bashrc:

    #each console has its own file to save PWD
    PrevDir=$(tty) 
    PrevDir=/tmp/prev-dir${PrevDir////-}
    #don't ls when shell launched
    echo $PWD > $PrevDir
    LsAfterCd() {
        [[ "$(< $PrevDir)" == "$PWD" ]] && return 0

        ll --color=always | sed 1d

        echo $PWD > $PrevDir
    }
    PROMPT_COMMAND=LsAfterCd

In bash you cannot recur to aliases for action that require parameter. For this there are functions. So put in your ~/.bashrc the following

mycd() {
  cd "$1"
  ls
}
  • 4
    cd "$1" && ls would be better. – Gilles Sep 9 '11 at 23:39
  • To allow a parameter for the ls command, I use function mycd { builtin cd $1 && ls $2 }. Now you can call the command e.g. mycd .. -la – Christian Schulzendorff Feb 19 '16 at 9:20
  • @ChristianSchulzendorff: better to use the quotes: function mycd { builtin cd "$1" && ls "$2" } . – enzotib Feb 19 '16 at 16:58
  • Does not work, I just tried it. The file was empty, but after adding your code, nothing changed. – Black Jun 25 at 14:20

Why not add an alias to your .bashrc file?

Something like:

alias cdls='cd "$@" && ls'
  • @don_crissti A funtion and an alias are different things. So why not? – Jodka Lemon Dec 16 '15 at 14:09

Place the below code in the .profile and it works. Tested on HP-Unix box.

cdl()
{
if [ "$#" = 0 ]; then
cd ~ && ls -ltr
elif [ -d "$@" ]; then
cd "$@" && ls -ltr
else
echo "$@" directory not found!!!
fi
}

#SET YOUR ALIAS TO CD
alias cd="cdl"

Even more handy - with ability to go back in history:

function cd() {
    if [ -d "$@" ]; then
        echo -n "Stack: "
        pushd "$@"
        ls
    else
        builtin cd "$@"
    fi
}
function popd() {
    builtin popd "$@" && ls
}

When you change directory a line with: Stack: (current_dir) (previous_dir) ... will be shown, then ls output. To go back in dirs history just pop this command: popd.

I added else so you'll see an error when trying to go to a wrong directory.

  • if you just do cd - it will bring you to your last dir that you were in. – Ian Nov 13 '17 at 12:25

I think it's good to enable ls's options in this way as cd takes no option.

cdls() {
  cd ${$#} && ls ${@:0:$#-1}
}
alias cd='builtin cd $1 && ls -l && builtin cd $1'
  • This add nothing that the other answers have not already covered. – jasonwryan Jul 17 '16 at 3:58

protected by Kusalananda Sep 30 '17 at 19:34

Thank you for your interest in this question. Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).

Would you like to answer one of these unanswered questions instead?

Not the answer you're looking for? Browse other questions tagged or ask your own question.