Reputation: 9562
This is the output of ls
command:
$ ls
addr.sh hello.txt test.sh xxx.txt
Here we have the same command with redirection to stderr:
$ ls 1>&2
addr.sh hello.txt test.sh xxx.txt
Which produces pretty much the same output.
However redirection to a regular file causes ls
to produce a multi-line output:
$ ls > xxx.txt
$ cat xxx.txt
addr.sh
hello.txt
test.sh
xxx.txt
Why and what is happening behind the scenes?
Upvotes: 1
Views: 110
Reputation: 140880
Why
Because someone programmed it that way.
what is happening
Your implementation of ls
checks if standard output is connected to a terminal device. If it is, it outputs a pretty printed output separated by spaces in a column-like fashion. If the output isn't a terminal device, it outputs a newline separated list.*
Checking if a file decriptor is opened on a terminal can be done with test -t FD
command that internally calls isatty()
C function.
ls
basically works like:
{ if [ -t 1 ]; then ls -C; else ls -1; fi }
# From man ls:
# -C list entries by columns
# -1 list one file per line.
Many utilities change their behavior when the output is not a terminal device.
*Note that POSIX ls specification mandates the output to be list of one entry per file when the output is not a terminal The default format shall be to list one entry per line to standard output; the exceptions are to terminals [...]
.
behind the scenes?
I assume you have coreutils ls
implementaion. At coreutils/ls.c#L1886 program just checks if isatty(STDOUT_FILENO)
and depending on that sets quoting style and column-like or newline-like output.
Upvotes: 3