如何使用 echo 覆蓋標準輸出?
我們知道要覆蓋
bar.txt
,我們可以使用這個:echo "foo" > bar.txt
但是我們怎樣才能覆蓋到標準輸出呢?我試過這個命令:
echo "foo" >
但它失敗了。我想要這個,因為我想列印這樣的東西:
Hello world I'm HERE
一次一個詞,我想刪除前一個詞(在標準輸出上一次一個詞)。
echo
始終輸出到其標準輸出1。echo foo
總是做一個write(1, "foo\n")
.當您這樣做
echo foo > file
時,shell 會將echo
命令的標準輸出更改為新file
文件。echo foo
然後仍然執行 awrite(1, "foo\n")
但這次它的標準輸出(它的文件描述符 1)指向file
,而不是它從 shell 繼承的標準輸出。如果您想寫入標準輸出而不重定向標準輸出,只需編寫:
echo foo
如果您希望 stdout 指向的資源在 each 之前重新打開(並截斷)
echo
,那麼這就比較棘手了。在 Linux(和僅限 Linux)上,您可以執行以下操作:
echo foo > /dev/fd/1 echo bar > /dev/fd/1 # now the file stdout points to (if it's a regular file) contains "bar"
在 Linux 上,
/dev/fd/1
是在標準輸出上打開的文件的符號連結。所以再次打開它>
會截斷它(在其他 Unices 上,> /dev/fd/n
就像dup2(n,1)
它不會截斷文件一樣)。但是,如果 stdout 進入套接字,那將不起作用。否則,您可以呼叫
ftruncate()
stdout (fd 1) 來截斷它:perl -e 'truncate STDOUT,0' echo foo perl -e 'truncate STDOUT,0' echo bar
相反,如果您想要這些詞,當 stdout 是在螢幕上相互覆蓋的終端時,您可以使用終端控製字元來影響游標定位。
printf %s FOO printf '\r%s' BAR
將有 BAR 覆蓋 FOO 因為
\r
是指示終端將游標移動到行首的控製字元。如果你這樣做:
printf %s FOOBAR printf '\r%s' BAZ
但是,您會
BAZBAR
在螢幕上看到。您可能希望使用另一個控制序列來清除該行。雖然\r
輸入的含義是通用的,但清除螢幕的控制順序因終端而異。最好是查詢 terminfo 數據庫tput
以找出它:clr_eol=$(tput el) printf %s FOOBAR printf '\r%s%s' "$clr_eol" BAZ
1如果使用 Korn 或 Z shell,另一個支持寫入其他文件描述符的輸出命令是
print -u2 FOO
例如寫入FOO
’echo
和在 Bourne-like shell 中,您可以echo >&2 FOO
實現相同的結果。echo
仍在寫入其標準輸出,但已使用>&2
shell 重定向運算符將其標準輸出複制為 shell 的標準錯誤