I just decided to give zsh a go against Bash and came across some unhandy behaviour about which I couldn't find anything on the net:

If you do a ls | grep foo in Bash, the ls only contains one file per line so that grep only outputs the matching files. It seems like somewhere (and since I couldn' find anything in the config I think it must be the Bash code itself), the -1 option is passed to ls.
zsh however doesn't do that magic: If you pass ls without further options to grep, it does just that and you also get result's which coincidentally appeared on the same line as a match.

My idea to achieve the Bash behaviour in zsh would have been to detect whether a ls output will be piped into grep and define something like an alias for such cases. But I'm not sure how and if that's possible at all.

Update: As larsks points out below, Bash doesn't do anything special here and it's really ls which is supposed to work that way if the output doesn't go to a terminal.

Nevertheless, here's what happens to me:

> ls
a  b  c  d  e  f  g  h

bash$ ls | grep b

zsh> ls | grep b
a  b  c  d  e  f  g  h

I've been able to reproduce that on Ubuntu 11.10 with zsh 4.3.11 and GNU coreutils 8.5 as well as on a Debian Squeeze machine with zsh 4.3.10.

Update 2: While investigating a bit more, I found out that this error only appears when the grml .zshrc is active. There must be something in there which which opens a terminal for the output if it is piped. Does anybody know what to look for?


2 Answers 2


According to the ls documentation, this behavior is intrinsic to the ls command:

     List one file per line.  This is the default for `ls' when standard
     output is not a terminal.

When piping to another process with |, stdout should not be a tty. bash isn't doing anything special.

In all of my tests, using zsh version 4.3.15 on Linux and zsh 4.3.11 on OS X, ls behaves the same way under zsh as it does under bash. If you really believe you're seeing different behavior, please update your question with (a) the version of zsh you're using and (b) a complete example of the problem, showing both the actual directory contents and the specific command line you're using.


By narrowing down to the responsible line in .zshrc, I could figure that out by myself:

It's in fact much simpler than some kind of virtual terminal for piping. The error results from line 1477 of grml's config which looks like this:

alias ls='ls -b -CF '${ls_options:+"${ls_options[*]} "}

So the ls command obviously isn't called directly, but via the alias. And that one explicitly activates the column output through the -C option.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .