天天看點

重定向點滴

< 标準輸入重定向[StdIN]。代碼為0  預設接收來自鍵盤的輸入。

>  标準輸出重定向(正确) [StdOUT]。代碼為1。預設輸出到終端視窗。

2> 标準輸出重定向(錯誤)[StdErr]。 代碼為2。預設輸出到終端視窗。

可以将輸出重定向到其他輸出裝置

#tty

/dev/pts/0

#echo "this msg from pts/0" > /dev/pts/1

StdIN和StdOUT可以被重定向到檔案

格式:

指令 重定向符号 檔案名

支援的操作符号包括:

> StdOUT重定向到檔案

< StdIN 重定向輸入

2> 把ErrStdOUT重定向到檔案

&> 把所有輸出(不管正确錯誤)覆寫重定向到檔案

&>> 把所有輸出(不管正确錯誤)追加重定向到檔案

> 檔案内容會被覆寫

>> 原有内容基礎上追加内容

set –C 禁止将内容覆寫已有檔案,但可追加

set +C 允許覆寫

>| file 強制覆寫,會丢失原有内容

/dev/null 重定向到此裝置将會無任何資訊輸出

2>&1 将 StdErr重定向至StdIN輸出,即将錯誤定向到正确1輸出

1>&2 将 StdOUT重定向至StdErr輸出,即将正确定向到錯誤2輸出

若後面出現多個重定向符時,預設就是并行運作,一定要注意各自己的輸出至哪裡

> 或  >> 在沒有内容改變重定向的時候,不會改變時間戳

單行重定向輸入回車的時候就會開始重定向,如果是等待輸入的情況下,必須有ctrl+d結束将會回車一行定向一行

多行重定向輸入必須成對詞使用

#cat > all.log <<EOF

> 1 LINE

> 2 LINE

> 3 LINE

> EOF

#cat all.log

1 LINE

2 LINE

3 LINE

|  管道    用來連接配接指令

指令1 | 指令2 | 指令3 | …

将指令1的STDOUT發送給指令2的STDIN,指令2的STDOUT發送到指令3的STDIN

STDERR錯誤重定向不能通過管道轉發,可利用2>&1 或 |& 轉化後實作

(errcmd;hostname) 2>&1 > /app/all.log

#aa 2>&1|tr 'a-z' 'A-Z'

-BASH: AA: COMMAND NOT FOUND

#aa |& tr 'a-z' 'A-Z'         此種方法較新,需要考慮到相容性

最後一個指令會在目前shell程序的子shell程序中執行用來組合多種工具的功能

ls | tr 'a-z' 'A-Z'

(把ls的輸出結果作為tr的輸入,再将輸入的内容中的小寫字母轉化為大寫字母後輸出到螢幕)

#cat linux.txt |mail -s h6 root

- 符号

示例:

将 /home 裡面的檔案打包,但打包的資料不是記錄到檔案,而是傳送到 stdout,

經過管道後,将 tar -cvf - /home 傳送給後面的 tar -xvf - , 後面的這個 - 則是取前一個指令的

stdout, 是以,就不需要使用臨時file了

tar -cvf - /home | tar -xvf -

标準輸出和錯誤輸出各自定向至不同位置

COMMAND > /path/to/file.out 2> /path/to/error.out

合并标準輸出和錯誤輸出為同一個資料流進行重定向

COMMAND > /path/to/file.out 2>&1 (順序很重要)

合并多個程式的STDOUT

( cal 2007 ; cal 2008 ) > all.txt

執行個體示範:

1.指令嵌套輸出

#echo `uname -n` > a

#cat a

a69.hunk.edu

2.連續執行指令時應該用小括号,否則将會隻比對重定向符最近的一個

#(ll;pwd;hostname) > c

#cat c

-rw-r--r--. 1 root root 47 Nov 13 21:24 a

-rw-r--r--. 1 root root  0 Nov 13 21:23 b

-rw-r--r--. 1 root root  0 Nov 13 21:26 c

/app

3.将StdIN與StdOUT分别輸出至不同檔案

方法1:

#(errcdm;hostname) > /app/true.log 2> /app/err.log

此行指令解釋:()内的正确1輸出定向到/app/true.log,錯誤2輸出定向到/app/err.log輸出。

是以,檔案内應該會有2個檔案分别記錄

#cat true.log err.log

-bash: errcdm: command not found

4.将StdIN與StdOUT分别輸出同檔案

#(errcmd;hostname) > /app/all.log 2>&1

-bash: errcmd: command not found

方法2:

# (errcmd;hostname) &> all.log  此寫法較新,不适用于centos 3,4

2>&1 用法

#(err;hostname) > /app/all.log 2>&1

此行指令解釋:()内的正确輸出定向到/app/all.log,錯誤2輸出定向到1輸出。

是以,檔案内應該會有2條記錄

-bash: err: command not found

#(errcmd;hostname) 2>&1 > /app/all.log

此行指令解釋:()内的錯誤輸出2定向到正确1輸出,預設就是螢幕輸出,正确1輸出定向到/app/all.log輸出。是以,檔案内應該會有1條記錄

#((errcmd;hostname) 2>&1) > /app/all.log

此行指令解釋:()内的錯誤輸出2定向到正确1輸出,預設就是螢幕輸出,正确1輸出到螢幕,是以,整個外部括号内就是2條資訊輸出,是以,檔案内應該會有2條記錄

1>&2 用法

#(errcmd;hostname) 2> /app/all.log 1>&2

此行指令解釋:()内的錯誤輸出定向到/app/all.log,正确1輸出定向到2輸出。

/dev/null用法

#(errcmd;hostname) 2> /dev/null

此行指令解釋:()内的錯誤輸出定向到/dev/null,正确1輸出到螢幕

是以,螢幕中内應該會有1條正确顯示

嵌套括号

#((errcmd;hostname) 2>&1) > /app/all.log

此行指令解釋:2>&1會将錯誤2定向到1上,是以整個括号内就是2條正确資訊定向 /app/all.log

是以,檔案中内應該會有2條記錄顯示

#((errcmd;hostname) 1>&2 ) > /app/all.log

此行指令解釋:1>&2會将正确定向到2的輸出上,也就是終端視窗上,是以整個括号内就是2條錯誤資訊,那麼括号外面是1正确才會定向 /app/all.log,是以檔案中内不會有記錄顯示,隻會顯示在螢幕

#cat /app/all.log

#

set –C

禁止将内容覆寫已有檔案,

#set -C

#ls > all.log

-bash: all.log: cannot overwrite existing file

但可以>>追加

#ll >> all.log

-rw-r--r--. 1 root root  75 Nov 13 22:37 all.log

-rw-r--r--. 1 root root   0 Nov 13 21:23 b

-rw-r--r--. 1 root root 152 Nov 13 21:26 c

更牛逼的就是強制>|  ,但是, 這個是覆寫清空原有内容

#echo new >| all.log

new

重定向到多個目标( tee)

指令1 | tee [-a ] 檔案名 | 指令2

把指令1的STDOUT先儲存在檔案中,同時StdOUT做為指令2的輸入

#hostname|tee host.out|tr 'a-z' 'A-Z'

A69.HUNK.EDU

#cat host.out

-a 追加

使用場景:

儲存不同階段的輸出

複雜管道的故障排除

同時檢視和記錄輸出

打開的檔案都有一個fd: file descriptor (檔案描述符)

使用exec可以定義一個檔案描述符

把host.out檔案用檔案描述符8來定義

#exec 8<>host.out

#ls /proc/$$/fd/ -l

lrwx------. 1 root root 64 Nov 14 16:54 8 -> /app/app/host.out

#cat /proc/$$/fd/8

#echo aa >> /proc/$$/fd/8

#cat /app/app/host.out

aa

取消定義關系

#exec 8>-  或 exec 8>&-

[root@a69 app]#ll /proc/$$/fd

lrwx------. 1 root root 64 Nov 14 16:54 8 -> /app/app/-

小小總結,如有錯誤,歡迎指正。謝謝

本文轉自 ljpwinxp 51CTO部落格,原文連結:http://blog.51cto.com/191226139/2047016