Search code examples
bashechowc

Why echo splits long lines in 80 chars when printing within quotes? (And how to fix it?)


Echoing without quotes... 1 line. Fine.

$ echo $(ls -1dmb /bin/*) > test
$ wc -l test
1 test

Echoing with quotes... 396 lines. Bad.

$ echo "$(ls -1dmb /bin/*)" > test
$ wc -l test
396 test

The problem comes when using echo for writing a file and expanding a long variable.

Why does this happen? How to fix it?


Solution

  • ls is detecting that your stdout is not a terminal.

    check the output of ls -1dmb /bin/* | cat vs ls -1dmb /bin/*. It's ls, who is splitting the output.

    Similarly, for ls --color=auto case, color option is used, based on whether the stdout is terminal or not.

    When quotes are used, echo is provided with a single arguments, which has embedded newlines, spaces, which are echoed as-is to file.

    When quotes are not used, echo is provided multiple arguments, which are split by the IFS. Thus echo prints all of them in a single line. But, don't skip these quotes...

    How to fix it:

    I think, the splitting always occurs at the end of some file name & never in between a filename. So one of these 2 options may work for you:

    ls -1dmb /bin/* | tr '\n' ' ' >test
    ls -1dmb /bin/* | tr -d '\n' >test