Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does the redirection symbol change the behavior of ls?

Tags:

linux

bash

unix

So, I have always had doubts about how redirection works in the following situations:

  1. I type "ls" and all the filenames are separated by white spaces:

    test$ touch a b c
    test$ ls
    a b c
    
  2. I use a ">" to redirect STDOUT to a file:

    test$ ls > ls.txt
    test$ cat ls.txt 
    a
    b
    c
    ls.txt
    

It is interesting to see that the format changes, with the filenames separated by newline characters. It seems that the output is generated by ls -1.

Why is the output in the latter case different from that in the former case? Can ls actually see the ">" symbol so it changes its behavior?

like image 757
Yu Fu Avatar asked Aug 01 '13 14:08

Yu Fu


People also ask

How does redirection work in Linux?

Redirection is a feature in Linux such that when executing a command, you can change the standard input/output devices. The basic workflow of any Linux command is that it takes an input and give an output. The standard input (stdin) device is the keyboard. The standard output (stdout) device is the screen.

How does shell redirection work?

Before a command is executed, its input and output may be redirected using a special notation interpreted by the shell. Redirection allows commands' file handles to be duplicated, opened, closed, made to refer to different files, and can change the files the command reads from and writes to.

Which symbol should I use to redirect the standard output to a file?

Redirecting output to append to a file When the notation > > filename is added to the end of a command, the output of the command is appended to the specified file name, rather than writing over any existing data. The >> symbol is known as the append redirection operator.

What is the difference between redirection and piping in Linux?

The difference between a pipe and a redirect is that while a pipe passes standard output as standard input to another command, a redirect sends a output to a file or reads a file as standard input to a command.


2 Answers

ls tests its output stream to see whether it is a terminal, and it modifies its behavior depending on that.

This is documented; the man page for ls documents several things that depend on whether the output is a terminal:

  • If the output is a terminal, -C (for multi-column output) is a default, otherwise -1 (one-column) is a default.
  • If -l or -s is used and the output is a terminal, a sum for all file sizes or blocks, respectively, is printed on a line before the listing.
  • If the output is a terminal, -q is a default. This prints non-graphic characters as “?”. Otherwise, -v and -w are defaults. I am a bit unclear on the difference between -v and -w. The documentation I have says -v forces “unedited printing of non-graphic characters” and -w forces “raw printing of non-printable characters.”
like image 187
Eric Postpischil Avatar answered Sep 18 '22 23:09

Eric Postpischil


It cannot see the symbol (which is interpreted by the shell), but it can find out whether the output is going to a terminal.

In order to organize files nicely into the columns, ls needs to know the width of the terminal. When the output device is not a terminal, it just doesn't know how to format its output.

Another nice consequence of this behavior is that you can do things like ls | wc -l without worrying about multiple files on the same line. (You still have to worry about file names containing newlines, though.)

like image 36
Roman Cheplyaka Avatar answered Sep 17 '22 23:09

Roman Cheplyaka