Make cd automatically ls
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
Related videos on Youtube
RobKohr
Updated on September 18, 2022Comments
-
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 anls
.I fiddled with my
.bashrc
for a while, but couldn't figure out how to make it happen. -
enzotib over 12 yearsThat 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 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 over 12 yearsFirst: 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 over 12 yearsOk 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 over 12 yearsI would remove the downvote, but cannot if I do not understand why it does not work here.
-
Gilles 'SO- stop being evil' over 12 yearsThe alias won't work. Aliases don't take arguments, the
$1
will remain in the alias expansion. -
Gilles 'SO- stop being evil' over 12 years
-
Mark Norgren over 12 yearsThe 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 almost 11 yearsI have something similar, but I call it
cdl
, since the point is to save typing. -
syntagma over 9 yearsWhat exactly does
[ -z "$PS1" ] && return
do? -
Jodka Lemon over 8 years@don_crissti A funtion and an alias are different things. So why not?
-
Christian Schulzendorff about 8 yearsTo 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 about 8 years@ChristianSchulzendorff: better to use the quotes:
function mycd { builtin cd "$1" && ls "$2" }
. -
Kusalananda over 7 yearsAnother way to check for interactivity is to look for
i
in"$-"
:case "$-" in *i*) ;; *) return ;; esac
. -
sgsudhir over 6 yearsDoes 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 over 6 years@Kusalananda & frabjous: Are there cases where one should be used instead of the other?
-
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 over 6 years@Kusalananda That lines up perfectly with what I was finding as well. I'll check
$-
. Thanks a lot :D -
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 yourexport PS1
after the check! -
Kusalananda over 6 years@Swivel There shouldn't be a reason to export
PS1
. -
Ian over 6 yearsif you just do cd - it will bring you to your last dir that you were in.
-
Black almost 6 yearsWhere is .bashrc?!
-
Black almost 6 yearsDoes not work, I just tried it. The file was empty, but after adding your code, nothing changed.
-
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 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 over 5 yearsUmm...
cd
does take options. -
Ghos3t about 5 yearsThis 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 about 5 yearsI 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 about 5 yearsThis doesn't work.
-
Emobe over 4 yearsi 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 typecdls
defeats the point and might as well just do the two commands but that's just me -
a3y3 over 4 yearsYep, using an alias simply lists contents in that directory, but doesn't actually cd to there.
-
Hashim Aziz about 4 yearsWhat does the @ mean here? I haven't seen that syntax for an argument before.
-
Slawa almost 4 yearsA little variation to show only as much file as would fit the screen. ``` builtin cd "$@" && ls -la | head -n $(tput lines) ```
-
Kevin over 3 yearsBy "simplified" do you mean "get rid of the PrevDir file"?
-
Kangarooo about 3 yearsHow to undo this?
-
ajinzrathod almost 3 yearsWhat is
-F
for -
Filip Górny over 2 yearsthis works for me also in zsh
-
G-Man Says 'Reinstate Monica' over 2 yearsWhy not just do
builtin cd
?? -
they over 2 yearsNote that
cd
with no argument, is not the same ascd
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 functioncd
if you callcd
ascommand cd
inside the function. -
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 over 2 years@they Would be great if
readonly
would work on functions -
they over 2 years
readonly -f
works on functions inbash
. Seehelp readonly
and the manual. Also, I have not seen standard utilities say things about "no args" or "illegal args". -
Luciano Andress Martini over 2 yearsBecause builtin cd will not do automatic ls when entering a folder, that is what is asked on the question.
-
G-Man Says 'Reinstate Monica' over 2 yearsSorry, 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 withcd() { builtin cd $*; ls; }
. … (Cont’d) -
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' 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 thebuiltin
command). … (Cont’d) -
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 not 100% sure, but I believe thatcommand cd
would work, and it is POSIX-compliant. -
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 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 over 2 yearsIn 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' over 2 yearsI’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 firstaltercd
version, announcing that it was POSIX compatible. -
Luciano Andress Martini over 2 yearsYeah I think I did not remember. Sorry man It was years ago! So you think I can use command cd that is POSIX?
-
Admin about 2 years@Jack Yes: askubuntu.com/a/97766/356625