0

I created the following function is ~/.bashrc:

function cl {cd $1; echo $1; ls -al $1}

(I put the echo command in there just to see what it's actually reading in)

In my home directory, I created a folder called "example folder", and I tried cl "example folder" and cl example\ folder and cl ~/"example folder". All of them printed out the same thing:

-bash: cd: too many arguments
example folder

Followed by the ls command, which just lists out my current directory.

So, is there a way around this? How can I pass in a directory that contains spaces?

1 Answers1

2
function cl {cd $1; echo $1; ls -al $1}

is closer to zsh syntax than bash syntax, but even then, still has many issues.

In bash

  • you need whitespace after {, and } to be preceded by a command delimiter (;, &, newline, though ) would also do). Doesn't apply to zsh.
  • Parameter expansions must be quoted or otherwise they undergo split+glob. Doesn't apply to zsh.
  • If you pass variable data to be meant to be a regular argument, not an option, you should make sure you precede it with the end-of-option marker (--) to avoid the data be taken as an option if it starts with -.
  • you're not checking the exit status of cd after running the next command.
  • echo can't be used to output arbitrary data. Use printf instead.
  • after you have cded into $1, ls -la $1 (or the more correct ls -la -- "$1") won't work anymore if $1 was a relative path. Most likely you want only ls -la (or ls -lA).
  • In scripts, you generally want to use cd with -P, and after having made sure $CDPATH is unset or empty (CDPATH= cd -P -- "$1") so that it behaves more like the chdir() of any other language. Does probably not apply if the function is to be used from an interactive shell though.
  • function f { ...; } is the ksh syntax for function definition. In bash, there's little reason to prefer that over the standard f() { ...; } syntax.

So:

cl() {
  cd -- "$1" || return
  printf '%s\n' "$1"
  ls -Al
}

Note that when not passed any argument, cd changes directory to your home directory (cd is like cd ~ or cd "$HOME").

However, here when cl is called with no argument "$1" expands to one empty argument instead of no argument at all (and cd would likely choke on that). To call cd with no argument if cl is called with no argument (so that cl alone brings you to your home directory and list the files there), you'd replace "$1" there with ${1+"$1"}. Or you could call cd with the same list of arguments that cl received using "$@" so you can do for instance cl -P ../bin or cl -- -dir-whose-name-starts-with-dash.

Then, you'd likely want to print the current working directory after cd rather than the first argument with either printf '%s\n' "$PWD" or just pwd.

cl() {
  cd "$@" || return
  pwd
  ls -Al
}

More reading: