echo
always outputs to its stdout1. echo foo
always does a write(1, "foo\n")
.
When you do echo foo > file
, the shell changes the stdout for the echo
command to a new file
file. echo foo
then still does a write(1, "foo\n")
but this time its stdout (its file descriptor 1) points to file
, not to the stdout it inherits from the shell.
If you want to write to stdout without that stdout being redirected, just write:
echo foo
If you want the resource pointed to by stdout to be reopen (and truncated) before each echo
, then that's trickier.
On Linux (and Linux only), you can do:
echo foo > /dev/fd/1
echo bar > /dev/fd/1
# now the file stdout points to (if it's a regular file) contains "bar"
On Linux, /dev/fd/1
is a symlink to the file that is open on stdout. So opening it again with >
will truncate it (on other Unices, > /dev/fd/n
is like dup2(n,1)
so it won't truncate the file). That won't work if stdout goes to a socket though.
Otherwise, you can call ftruncate()
on stdout (fd 1) to truncate it:
perl -e 'truncate STDOUT,0'
echo foo
perl -e 'truncate STDOUT,0'
echo bar
If instead, you want those words, when stdout is a terminal to overwrite each other on the screen, you can use terminal control characters to affect the cursor positioning.
printf %s FOO
printf '\r%s' BAR
will have BAR overwrite FOO because \r
is the control characters that instructs the terminal to move the cursor to the beginning of the line.
If you do:
printf %s FOOBAR
printf '\r%s' BAZ
however, you'll see BAZBAR
on the screen. You may want to use another control sequence to clear the line. While \r
as meaning carriage return is universal, the control sequence to clear the screen varies from one terminal to the next. Best is to query the terminfo database with tput
to find it out:
clr_eol=$(tput el)
printf %s FOOBAR
printf '\r%s%s' "$clr_eol" BAZ
1 if using the Korn or Z shell, another outputting command that supports writing to other file descriptors is print
: print -u2 FOO
for instance writes FOO
to print
's stderr. With echo
and in Bourne-like shells, you can do echo >&2 FOO
to achieve the same result. echo
is still writing to its stdout, but its stdout has been made a duplicate of the shell's stderr using the >&2
shell redirection operator
>
operator won't append to the file actually it overwrites the file.And if you just sayecho "foo"
orecho "foo" >&1
it prints onstdout
. – Thushi Aug 21 '14 at 12:06