第五章 linux重定向和管道
重定向和管道
標準輸入和輸出:
程序:指令+數據
讀入數據: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. > >Detailswhenyou‘reon-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重定向和管道