1. 程式人生 > >第五章 linux重定向和管道

第五章 linux重定向和管道

控制 windows 空白 設備 example 替換 刪除fstab num 研究

重定向和管道

標準輸入和輸出:

程序:指令+數據

讀入數據:Input

輸出數據:Output

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

Linux給程序提供三種I/O設備

  • 標準輸入(STDIN)-0默認接受來自鍵盤的輸入
  • 標準輸出(STDOUT)-1默認輸出到終端窗口
  • 標準錯誤(STDERR)-2默認輸出到終端窗口

I/O重定向:改變默認位置

[root@localhost /app]#ls >/dev/pts/7

本終端窗口不進行輸出,將結果輸出到別的終端窗口。

把輸出和錯誤重新定向到文件:

STDOUT和STDERR可以被重定向到文件

命令 操作符號 文件名

支持的操作符號包括:

> 把STDOUT重定向到文件

2>把STDERR重定向到文件

&>把所有輸出重定向到文件

> 文件內容會被覆蓋

set –C 禁止將內容覆蓋已有文件,但可追加

>| file 強制覆蓋

set +C 允許覆蓋

>> 原有內容基礎上,追加內容,原文件存在不刷新時間戳。

2>覆蓋重定向錯誤輸出數據流

2>>追加重定向錯誤輸出數據流

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

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

合並標準輸出和錯誤輸出為同一個數據流進行重定向

&>覆蓋重定向

&>> 追加重定向

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

COMMAND >> /path/to/file.out2>&1

():合並多個程序的STDOUT

(cal2007;cal2008)> all.txt

[root@localhost /app]#(hostname;whoami;ls)>a.txt
[root@localhost
/app]#cat a.txt
localhost.localdomain
root
a aaaa f
lost
+found

加上( )把三個命令的結果全部添加到文件a.txt中。如果不加( )由於優先級問題就會先執行>即a.txt中的內容為ls執行的結果。

[root@localhost /app]#(error;hostname)>aaa.log   2>&1

把錯誤的重定向到標準輸出,而標準輸出是放到aaa.log文件中的。

[root@localhost /app]#(error;hostname)  2>&1  >a

-bash: error: command not found

2>&1放前面和後面是完全不一樣的結果,前一條命令直接變成對的輸出到屏幕,後一條命令是對的直接輸出到文件。

[root@localhost /app]#((error;hostname) 2>&1) >a

[root@localhost /app]#cat a

-bash: error: command not found

localhost.localdomain

這樣加上( )經過轉換就可以了。

[root@localhost /app]#(error;hostname)&>aaa.log   

等價於上一條執行的命令。

[root@localhost /app]#ls >/dev/null

/dev/null是黑洞設備,不需要輸出到窗口的信息可以重定向到這裏。

[root@localhost /app]#(echo error 1>&2) > /dev/null

error

把對的轉化為錯的,顯示的結果不能標準輸出到/dev/null中

tr命令:

tr轉換和刪除字符

tr[OPTION]... SET1 [SET2]

選項:

-c–C --complement:取字符集的補集

-d--delete:刪除所有屬於第一字符集的字符

-s--squeeze-repeats:把連續重復的字符以單獨一個字符表示

-t--truncate-set1:將第一個字符集對應字符轉化為第二字符集

對應的字符

[:alnum:]:字母和數字 [:alpha:]:字母[:cntrl:]:控制(非打印)字符[:digit:]:數字 [:graph:]:圖形字符 [:lower:]:小寫字母[:print:]:可打印字符 [:punct:]:標點符號 [:space:]:空白字符 [:upper:]:大寫字母 [:xdigit:]:十六進制字符

從文件中導入STDIN:

使用<來重定向標準輸入

某些命令能夠接受從文件中導入的STDIN

tr‘a-z’‘A-Z’</etc/issue

該命令會把/etc/issue中的小寫字符都轉換成大寫字符

tr –d abc < /etc/fstab 刪除fstab文件中的所有abc中任意字符

cat > file

sunan

sunanblog.com

按ctrl+d離開,可以使用文件來代替鍵盤的輸入

cat > filea <fileb

[root@localhost /app]#tr 123 ab

123456123

abb456abb

3沒有代替的直接用b代替。

[root@localhost /app]#tr  -t 123 ab

12345123456

ab345ab3456

-t選項是截斷,相當於3不要了。

[root@localhost /app]#tr -d a-z<fstab

# A ,  ,    //

# S   (5), (8), (8) / (8)  

#

UUID=044064-970-41-9-74526493 /                       4            1 1

UUID=859743-0-49-26-803582 /                    4            1 2

UUID=0759--4156-25-23245 /                   4            1 2

UUID=435474-0-47-459-152686446                                 0 0
......

將文件中的小寫字母全部刪掉。

[root@localhost /app]#tr -d a-z<fstab >fstab2

[root@localhost /app]#cat fstab2

#
......

UUID=044064-970-41-9-74526493 /                       4            1 1

UUID=859743-0-49-26-803582 /                    4            1 2

UUID=0759--4156-25-23245 /                   4            1 2

UUID=435474-0-47-459-152686446                                 0 0
......

轉化過後重定向到新的文件中。

[root@localhost /app]#tr -d a-z<fstab >fstab

上面的命令執行會把fstab文件中的內容清空,在單一命令中,一次只能處理一次,打開的同時再重定向是不行的,只能換一個新的文件名。

[root@localhost /app]#tr -s a

asdfaaaaasdfsdfsaaaa

asdfasdfsdfsa

-s是將重復的a進行壓縮。

[root@localhost /app]#tr -dc a      

asdfvdssd

sdfas

sdfasdf

這條命令按回車是不會執行的,因為-c是取a的補集,-d是刪除,即除了a意思是包括\n回車也會當成輸入來執行,只能按Ctrl+d進行處理。

[root@localhost /app]#tr -dc a\n 

asdfsdfaaa

aaaa

這樣加上回車換行\n就可以了。

[root@localhost /app]#cat win.txt

a

b

c[root@localhost /app]#

查看windows上傳的win.txt文件

[root@localhost /app]#hexdump  -C win.txt

00000000  61 0d 0a 62 0d 0a 63                              |a..b..c|

00000007

查看windows上傳的文件的16進制編碼

[root@localhost /app]#cat linux.txt

a

b

c

[root@localhost /app]#

查看linux上的文件linux.txt,內容是一樣的。l

[root@localhost /app]#hexdump  -C linux.txt

00000000  61 0a 62 0a 63 0a                                 |a.b.c.|

00000006

查看Linux上的文件和Windows上傳文件內容一樣。但inux上以前為了節省空間,把回車和換行用一個換行表示,windows上回車是回車換行是換行。

[root@localhost /app]#tr -d \r <win.txt  >newwin.txt

[root@localhost /app]#hexdump  -C newwin.txt

00000000  61 0a 62 0a 63                                    |a.b.c|

00000005

這條命令就把windows文件轉換為linux文件了,說明windows中的文件和linux中的文件是不同的。

[root@localhost /app]#hexdump  -c linux.txt

0000000   a  \n   b  \n   c  \n                                       

0000006

[root@localhost /app]#hexdump  -c win.txt

0000000   a  \r  \n   b  \r  \n   c                                   

0000007

加小c選項可以直接看到回車和換行。

[root@localhost /app]#dos2unix  win.txt

dos2unix: converting file win.txt to UNIX format ...

[root@localhost /app]#hexdump  -c win.txt                  

0000000   a  \n   b  \n   c                                           

0000005

使用dos2unix可以直接windows文件格式直接轉換linux文件格式,當然,unix2dos是轉換回去。

[root@localhost /app]#cat aa        

aaa

bbb

ccc

[root@localhost /app]#tr \n \t <aa

aaa     bbb     ccc     [root@localhost /app]#

[root@localhost /app]#

[root@localhost /app]#tr \n \v <aa

aaa

   bbb

      ccc

         [root@localhost /app]#

將文件中的換行替換成水平tab鍵(水平制表符)和垂直tab鍵(垂直制表符)

把多行發送給STDIN:

使用“<<終止詞”命令從鍵盤把多行重導向給STDIN

直到終止詞位置的所有文本都發送給STDIN

有時被稱為就地文本(heretext)

mail -s "PleaseCall" root<<END

>HiSun,

> 

>Pleasegivemeacallwhenyougetin.Wemayneed

>todosomemaintenanceonserver1.

> 

>Detailswhenyoureon-site

>sun

>END

向root發送郵件

[root@localhost ~]#>/var/spool/mail/root

清空郵件。

[root@centos6 /]#mail -s "hello" root <<END

asddf

END

[root@centos6 /]#send-mail: warning: valid_hostname: numeric hostname: 9

send-mail: fatal: file /etc/postfix/main.cf: parameter mydomain: bad parameter value: 9

mai發送各種失敗,不知道為什麽,只能網上搜索答案。

[root@localhost ~]#hostnamectl set-hostname localhost 

需要上面這條命令,然後重啟機器就好了,網上答案說單機模式主機名需要改為localhost,至於為什麽再做研究。

管道:

管道(使用符號“|”表示)用來連接命令

命令1 | 命令2 | 命令3 | …

將命令1的STDOUT發送給命令2的STDIN,命令2的STDOUT發送到命令3的STDIN

STDERR默認不能通過管道轉發,可利用2>&1 或|& 實現

最後一個命令會在當前shell進程的子shell進程中執行用來

組合多種工具的功能

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

less :一頁一頁地查看輸入

ls-l/etc|less

mail:通過電子郵件發送輸入

echo"testemail"|mail-s "test"[email protected]

lpr:把輸入發送給打印機

echo"testprint"|lpr-Pprinter_name

管道中的 – 符號

示例:

將/home 裏面的文件打包,但打包的數據不是記錄到文件,而是傳送到stdout,經過管道後,將tar -cvf-/home 傳送給後面的tar -xvf-, 後面的這個-則是取前一個命令的stdout,因此,就不需要使用臨時file了

tar -cvf-/home | tar -xvf-

重定向到多個目標:

命令1 | tee[-a ] 文件名| 命令2

把命令1的STDOUT保存在文件中,做為命令2的輸入 -a 追加

使用:

保存不同階段的輸出

復雜管道的故障排除

同時查看和記錄輸出

[root@localhost /app]#ls |tee ls.out

lost+found

newwin.txt

win.txt

win..txt

[root@localhost /app]#cat ls.out

lost+found

newwin.txt

win.txt

win..txt

既想在屏幕輸出又想保存到文件可以用tee命令

[root@localhost /app]#pwd  |tee -a  ls.out

/app

[root@localhost /app]#cat ls.out         

lost+found

newwin.txt

win.txt

win..txt

/app

-a(append)選項是將新生成的內容追加到文件中。

第五章 linux重定向和管道