Make cd automatically ls

65,011

Solution 1

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 than 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 that 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.

Solution 2

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.

Solution 3

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.

Solution 4

Why not add an alias to your .bashrc file?

Something like:

alias cdls='cd "$@" && ls'

Solution 5

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
Share:
65,011

Related videos on Youtube

RobKohr
Author by

RobKohr

Updated on September 18, 2022

Comments

  • RobKohr
    RobKohr over 1 year

    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.

  • enzotib
    enzotib over 12 years
    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"
  • Mark Norgren
    Mark Norgren over 12 years
    @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.
  • enzotib
    enzotib over 12 years
    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.
  • Mark Norgren
    Mark Norgren over 12 years
    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.
  • enzotib
    enzotib over 12 years
    I would remove the downvote, but cannot if I do not understand why it does not work here.
  • Gilles 'SO- stop being evil'
    Gilles 'SO- stop being evil' over 12 years
    The alias won't work. Aliases don't take arguments, the $1 will remain in the alias expansion.
  • Gilles 'SO- stop being evil'
    Gilles 'SO- stop being evil' over 12 years
  • Mark Norgren
    Mark Norgren over 12 years
    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.
  • Keith Thompson
    Keith Thompson almost 11 years
    I have something similar, but I call it cdl, since the point is to save typing.
  • syntagma
    syntagma over 9 years
    What exactly does [ -z "$PS1" ] && return do?
  • Jodka Lemon
    Jodka Lemon over 8 years
    @don_crissti A funtion and an alias are different things. So why not?
  • Christian Schulzendorff
    Christian Schulzendorff about 8 years
    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
  • enzotib
    enzotib about 8 years
    @ChristianSchulzendorff: better to use the quotes: function mycd { builtin cd "$1" && ls "$2" } .
  • Kusalananda
    Kusalananda over 7 years
    Another way to check for interactivity is to look for i in "$-": case "$-" in *i*) ;; *) return ;; esac.
  • sgsudhir
    sgsudhir over 6 years
    Does not work for me. Tried @frabjous answer and it works: cd() { builtin cd "$@" && pwd; }; -- using standard bourne shell on macOS (Sierra 10.12.6)
  • sgsudhir
    sgsudhir over 6 years
    @Kusalananda & frabjous: Are there cases where one should be used instead of the other?
  • Kusalananda
    Kusalananda over 6 years
    @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.
  • sgsudhir
    sgsudhir over 6 years
    @Kusalananda That lines up perfectly with what I was finding as well. I'll check $-. Thanks a lot :D
  • sgsudhir
    sgsudhir over 6 years
    @Kusalananda I actually realized that when I was editing my .bashrc and noticed the custom prompt I wrote. Completely invalidates [ -z "$PS1" ]. For those who also export their own custom prompts, remember this! If you must use $PS1 for checking for interactive shell, remember to place your export PS1 after the check!
  • Kusalananda
    Kusalananda over 6 years
    @Swivel There shouldn't be a reason to export PS1.
  • Ian
    Ian over 6 years
    if you just do cd - it will bring you to your last dir that you were in.
  • Black
    Black almost 6 years
    Where is .bashrc?!
  • Black
    Black almost 6 years
    Does not work, I just tried it. The file was empty, but after adding your code, nothing changed.
  • Evan
    Evan almost 6 years
    @Black Typically your .bashrc would be in your home folder. ~/.bashrc. It'll be hidden since it starts with a period. If it doesn't exist, you can create it. That's a pretty elementary point, so you might want to read a basic bash tutorial before implementing suggestions like these.
  • Black
    Black almost 6 years
    @frabjous, If I would just had the time to do so... I made it work nevertheless by just reading this answer which explains it much much better and beginner friendly: unix.stackexchange.com/a/451781/124191
  • Kusalananda
    Kusalananda over 5 years
    Umm... cd does take options.
  • Ghos3t
    Ghos3t about 5 years
    This is the quickest and cleanest way of doing what the OP asked for. In my opinion, functions should be used for more complicated things, while making shortcuts for often typed commands are exactly what aliases exist for.
  • Ghos3t
    Ghos3t about 5 years
    I am having a strange issue with this alias, when I use it like this, cdls projec2, it will show all the files in the project 2 folder but not actually cd to that folder, instead, it will remain in the original folder.
  • temporary_user_name
    temporary_user_name about 5 years
    This doesn't work.
  • Emobe
    Emobe over 4 years
    i mean i'd rather have it override cd for the 100,000 different times i have to use it, rather than the one folder I could potentially come across with 100,000 files. Having to type cdls defeats the point and might as well just do the two commands but that's just me
  • a3y3
    a3y3 over 4 years
    Yep, using an alias simply lists contents in that directory, but doesn't actually cd to there.
  • Hashim Aziz
    Hashim Aziz about 4 years
    What does the @ mean here? I haven't seen that syntax for an argument before.
  • Slawa
    Slawa almost 4 years
    A little variation to show only as much file as would fit the screen. ``` builtin cd "$@" && ls -la | head -n $(tput lines) ```
  • Kevin
    Kevin over 3 years
    By "simplified" do you mean "get rid of the PrevDir file"?
  • Kangarooo
    Kangarooo about 3 years
    How to undo this?
  • ajinzrathod
    ajinzrathod almost 3 years
    What is -F for
  • Filip Górny
    Filip Górny over 2 years
    this works for me also in zsh
  • G-Man Says 'Reinstate Monica'
    G-Man Says 'Reinstate Monica' over 2 years
    Why not just do builtin cd??
  • they
    they over 2 years
    Note that cd with no argument, is not the same as cd with an empty argument. Neither is "illegal" and both have their uses. Also note that if $1 is set, then the faulty alias would definitely be doing something other than just listing the named directory/file. You can also call you shell function cd if you call cd as command cd inside the function.
  • hh skladby
    hh skladby over 2 years
    @they "no arg" or "illegal arg" are meant here as examples for error msgs you may be used to, not as an analysis of command grammar. The naming thing is a special case, anything after a definition may define it new, everyone has to care for themselves. For exposition it's helpful to have separate names.
  • hh skladby
    hh skladby over 2 years
    @they Would be great if readonly would work on functions
  • they
    they over 2 years
    readonly -f works on functions in bash. See help readonly and the manual. Also, I have not seen standard utilities say things about "no args" or "illegal args".
  • Luciano Andress Martini
    Luciano Andress Martini over 2 years
    Because builtin cd will not do automatic ls when entering a folder, that is what is asked on the question.
  • G-Man Says 'Reinstate Monica'
    G-Man Says 'Reinstate Monica' over 2 years
    Sorry, I wasn’t clear.  Why do you have function1 that defines function2, and function2 undefines itself and then calls function1 (causing function2 to be defined again)?  I guessed that you constructed that Rube Goldberg machine as a way of allowing a function called cd to call the actual, built-in “change directory” directive rather than calling itself recursively — which you could have more easily accomplished with cd() { builtin cd $*; ls; }. … (Cont’d)
  • G-Man Says 'Reinstate Monica'
    G-Man Says 'Reinstate Monica' over 2 years
    (Cont’d) …  Of course, if you had done that, it would have been essentially the same as frabjous’s answer from ten years ago (i.e., eight years before you posted your answer).  So, do you have any good reason for doing something fairly simple and easy in a complicated and hard way?
  • G-Man Says 'Reinstate Monica'
    G-Man Says 'Reinstate Monica' over 2 years
    (Cont’d) …  And I see now, by looking at the revision history, that you originally did use builtin cd; i.e., the first version of your answer was, essentially, a flawed copy of frabjous’s answer (flawed in that it used $* instead of "$@"), but then you rewrote it to be what it is now in an attempt to be POSIX-compliant (because POSIX doesn’t support the builtin command). … (Cont’d)
  • G-Man Says 'Reinstate Monica'
    G-Man Says 'Reinstate Monica' over 2 years
    (Cont’d) … But then later you deleted the explanation that you were jumping through hoops to be POSIX-compliant.  And I guess you forgot about that, inasmuch as that would have answered my question — you avoided builtin cd to be POSIX-compliant.  Which leaves me wondering why you deleted the explanation. … … … … … … … … … … … … … … … … … … P.S. I’m no‌​t 100% sure, but I believe that command cd would work, and it is POSIX-compliant.
  • hh skladby
    hh skladby over 2 years
    @they Yeh, you're right, I tend to forget the "-f"."no args" or "illegal args" were from their beginnings here written in double quotes with the intention to read them as if they were written in double quotes. I see no "further" way to try to "explain" this.
  • hh skladby
    hh skladby over 2 years
    @they, I was a little bit tired the hour ago, now let me tell you why I've put also the "-f" option for "readonly" in double quotes: It does not exist in POSIX. As it reads in the specs: "Read-only functions were considered, but they were omitted as not being historical practice or particularly useful. Furthermore, functions must not be read-only across invocations to preclude spoofing (...) of administrative or security-relevant (or security-conscious) shell scripts." The tag here is "Bash", so "-f", OK.
  • Luciano Andress Martini
    Luciano Andress Martini over 2 years
    In really I did not have thinked when I writed this question about using the builtin cd (and neither about being posix compilant) or even about command cd, when I wrote this I just see that the function was working, and thinked it was good enough. But your solution would be times better.
  • G-Man Says 'Reinstate Monica'
    G-Man Says 'Reinstate Monica' over 2 years
    I’m not sure I understand what you’re saying. When you first posted this answer (three years ago), you used builtin cd, and then 35 minutes later you posted the first altercd version, announcing that it was POSIX compatible.
  • Luciano Andress Martini
    Luciano Andress Martini over 2 years
    Yeah I think I did not remember. Sorry man It was years ago! So you think I can use command cd that is POSIX?
  • Admin
    Admin about 2 years