why $ ls > ls.out
causes ls.out to be included in list of names of files in current directory? why this way was chosen? Why not otherwise ?
When evaluating a command, redirection is always performed first: so by the time ls
runs the output file has been created already.
This is also the reason why reading and writing to the same file using redirection within the same command truncates the file: by the time the command runs the file has been truncated by the redirection already:
$ cat bar $ echo foo >bar $ cat bar foo $ <foo cat >bar $ cat bar $
From man bash
:
REDIRECTION
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.
First sentence, suggests that output is made to go somewhere other than stdin
with redirection right before the command is executed. Thus, in order to be redirected to file, file must first be created by the shell itself.
To avoid having a file, I suggest you redirect output to named pipe first, and then to file. Note the use of &
to return control over terminal to the user
DIR:/xieerqi skolodya@ubuntu:$ mkfifo /tmp/namedPipe.fifo DIR:/xieerqi skolodya@ubuntu:$ ls > /tmp/namedPipe.fifo & [1] 14167 DIR:/xieerqi skolodya@ubuntu:$ cat /tmp/namedPipe.fifo > ls.out
But why?
Think about this – where will be the output ? A program has functions like printf
, sprintf
, puts
, which all by default go to stdout
, but can their output be gone to file if file doesn’t exist in the first place ? It’s like water. Can you get a glass of water without putting glass underneath the sink first ?
There is also a nice article about Implementation of redirection and pipe operators in shell. Which shows how redirection could be implemented so $ ls > ls.out
could look like:
main() close(1); // Release fd no - 1 open("ls.out", "w"); // Open a file with fd no = 1 // Child process if (fork() == 0) exec("ls");
probably because it first creates a file ls.out and then writes output to it – incBrain 31 mins ago |
@edwardtorvalds What occurs to me is 1) not redirecting STDIN before would make the command not process anything until STDIN is redirected, so it would be just a waste a time 2) not redirecting STDOUT before would make the shell buffer the output internally, so it would be just a of time and memory. Two good reasons not to do it. – kos 10 mins ago | |||
@edwardtorvalds well think about this yourself – where will be the output ? A command has functions printf , sprintf , puts , which all by default go to stdin . . .It's like water. Can you get a glass of water without putting glass underneath the sink first ? – Serg 19 mins ago |