The Interesting bash behaviour

Why does this command (creating an empty folder, changing to it, touching a file, calling ls and then cating it), display two files?

root@ubuntu:~# mkdir a ; cd a ; touch b ; ls > c ; cat c
b
c

I believe that I should only get "b".

Upvotes: 4

Views: 79

Answers (4)

user2350426
user2350426

Reputation:

Understanding that the output of ls is being redirected to a file c, we need to look at the procedure the shell uses to execute such command.

When the shell process a command line (very simplified):

  1. Divides the line into tokens (usually at spaces).
  2. Interprets all tokens (which are commands, arguments, redirections).
  3. Sets up the structure of input and output, including any redirections.
  4. Execute the command, sending its output to the correct place.

As the output needs to be set at step 3, any file that will receive output, must exist, or be created if it does not exist.

Then, by the time the command (ls in this case) is executed, the file (c in this case) must already exist to receive the command output.

It is therefore correct to see the two files listed in the content of the file c.

Upvotes: 0

sehe
sehe

Reputation: 392833

The file is created (or truncated) so the output of ls can be redirected to it.

Hence, ls sees the file.

Upvotes: 1

Elliott Frisch
Elliott Frisch

Reputation: 201399

The redirection of standard output for the command

ls > c

Creates the file handle for c before the command ls executes. The touch b (and visibility of b are a red-herring). For example,

mkdir t ; cd t ; ls > a ; cat a

Will display a (because the > creates the a before ls is execd).

Upvotes: 3

Costi Ciudatu
Costi Ciudatu

Reputation: 38195

When you redirect the output of ls to the file c, it's a chicken and egg problem:

If c would not be created upfront, that would mean the shell would need to store the output in a buffer and (in the end) write that buffer to the file.

Since this is not the best approach in many cases (because of memory management, management of failure for commands that get interrupted before completion, etc.), the file gets created upfront.

Thus, the standard output for the command can be replaced with the newly created file and the command output can be streamed to that file.

Upvotes: 5

Related Questions