Reputation: 8042
What is the difference between those two commands?
while true; do date; sleep 1; done > /tmp/log
vs
while true; do date >> /tmp/log; sleep 1; done
Both append to file one line a time but seems that both do it different way.
I thought that first one won't append anything to file because the whole appending to file will happen after the loop ends, and because the loop is infinite nothing will ever be written to file.
Also how is possible that first one is appending to file when only one >
is used?
Upvotes: 3
Views: 2512
Reputation: 80931
This command:
while true; do date; sleep 1; done > /tmp/log
opens the file immediately (before the loop ever even runs) (and truncates any existing content in the file) and the commands that run inside the loop inherit the open file descriptor (fd) and any output is written to that fd as the output happens.
This command:
while true; do date >> /tmp/log; sleep 1; done
opens the file once each time through the loop (immediately before running the date
command). The >>
operator opens the file in append mode so the existing file contents are not truncated away.
Upvotes: 1
Reputation: 781068
In version 1, output is added to the file immediately because the date
command flushes its output when it exits, which writes everything to the standard output file.
Version 1 isn't appending to the file. It opens a file descriptor to the file when the loop starts, and empties the file when that happens. This descriptor stays open for the entire loop, and is inherited by each command in the loop as its standard output. Since it's not closed and reopened before each command, the file is not truncated each time -- they just write to the current position in the file.
Upvotes: 2
Reputation: 59611
For the first command
while true; do date; sleep 1; done
is seen as a "block". Anything that block outputs is printed to stdout
. You are simply redirecting the output of that block to a file.
Imagine you had the following shell script:
#!/bin/bash
while true; do date; sleep 1; done
And now you ran
script.sh > /tmp/log
You would also expect the log file to be continuously written to.
Upvotes: 2