1. 程式人生 > >第四章標準I/O和管道

第四章標準I/O和管道

I/O 重定向 管道

筆記整體起始時間:2018年4月2日18:55:25

本章內容

三種I/O設備

把I/O重定向至文件

使用管道

標準輸入和輸出

程序:指令+數據

讀入數據:Input

輸出數據:Output

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

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

標準輸入(STDIN) -0 默認接受來自鍵盤的輸入

標準輸出(STDOUT) -1 默認輸出到終端窗口

標準錯誤(STDERR) -2 默認輸出到終端窗口

I/O重定向:改變默認輸入輸出位置。

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

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

命令操作符號 文件名

支持的操作符號包括:

> 把STDOUT重定向到文件 1>

cat /etc/motd >f1

2> 把STDERR重定向到文件

cd /error 2>f2

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

cat /etc/issue /error2 &>f3 老系統可能不支持

> 重定向文件內容會被覆蓋

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

>| file 強制覆蓋

set +C 允許覆蓋

>> 原有內容基礎上,追加內容

如:

cat /error 2>file1 將錯誤輸出重定向覆蓋寫入 file1

cat /error 2>>file1 將錯誤輸出重定向追加寫入 file1

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

cmd >/path/file.out 2>/path/error.out 如:

cat /etc/motd /error >/root/Music/file1 2>/root/Music/file2

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

&> 覆蓋重定向

cat /etc/issue /error2 &>f3

&>> 追加重定向

cat /etc/issue /error2 &>>f3

cmd >out1 2>&1 覆蓋

cmd >>out2 2>&1 追加

其他寫法:

cmd 2>out3 >@2 偏門

(ls /error /data 2>&1)>ff6 括號

(ls /error /root >&2) 2>ff7 偏門的括號

錯誤寫法:cmd 2>&1 >ff5

順序很重要。

(),合並多個程序的STDOUT

(cal 2007;cal 1998) >cal

(cal,cal 8453531213554) >cal1 2>&1

or:&>cal2

有些命令輸出需要隱藏起來或者銷毀,重定向/dev/null,如

hostname > /dev/null

echo redhat |passwd --stdin wang &> /dev/null

tr命令:轉換和刪除字符

格式:

tr [OPTION]...set1 [set2]

如:

tr 'a-z' 'A-Z' 運行結果為:

[root@sentos7 ~]#tr 'a-z' 'A-Z'

afafj;k

AFAFJ;K

將輸入的小寫字母轉化為大寫字母

tr abc xyzo

[root@sentos7 ~]#tr abc xyzo

abcd

xyzd

將字符集1(abc)轉化為字符集2(xyzo)

若字符集2比較長,則多出部分無效

tr abcd xyz

[root@sentos7 ~]#tr abcd xyz

abcd

xyzz

如字符集1比字符集2長,則余下字符全部會轉化為字符集2的

最後一個字符

tr -t abcd xyz (--truncate-set1)

[root@sentos7 ~]#tr -t abcd xyz

abcd

xyzd

選項-t,要求一一對應,當字符集1比較長時,多出部分不再匹配字符

集2的最後一個字符

tr -s abcd xyz (--squeeze-set1)

[root@sentos7 ~]#tr -s abcd xyz

aaaaabbbbbcccccdddddaaaaaddddd

xyzxz

[root@sentos7 ~]#tr -s " "

a b c d

a b c d

把字符集1中,連續的重復的字符以單獨的字符顯示

如存在字符集2,則要求必須在字符集2中存在對應字符的字符才會才

會生效,如:

[root@sentos7 ~]#tr -s "abc " xyz

aabbcc bbdd ssaabb aaa

xyzyddzssxyzx

^C

[root@sentos7 ~]#tr -st "abc " xyz

aabbcc bbdd ssaabb aaa

xyz ydd ssxy x

^C

[root@sentos7 ~]#tr -s "abc " xyzo

aabbcc bbdd ssaabb aaa

xyzoyddossxyox

^C

[root@sentos7 ~]#tr -s "abc " "xyz "

aabbcc bbdd ssaabb aaa

xyz ydd ssxy x

tr -d abc

[root@sentos7 ~]#tr -d abc

aaabbbbcccddddeeeaafff

ddddeeefff

^C

刪除字符集1中的字符,不可加字符集2,否則報錯

tr -c abc x 取字符集的補集替換成x

[root@sentos7 ~/Music]#tr -c abc x

fafjakl;uifajl

xaxxaxxxxxxaxxx[root@sentos7 ~/Music]#

tr -dc abc 刪除abc以外的所有字符,默認按ctrl+D輸出

[root@sentos7 ~/Music]#tr -dc abc

jafkabbafaaaaccccafjifiejfa

aabbaaaaaccccaa[root@sentos7 ~/Music]#

字符集支持glob通配符

\nnn character with octal value NNN (1 to 3 octal digits)

八進制數nnn代表的ASCII字符

\\ backslash \

\a audible BEL 可聽見聲音

\b backspace 退格

\f form feed 換頁

\n new line 換行

\r ruturn 回車

\t horizontal tab 水平tap

\v vertical tab 垂直tap

[:alnum:] [:alpha:] [:digit:] [:lower:] [:upper:]

[:xdigit:] [:punct:] [:space:] [:gtaph:] [:cntrl:]

[:print:]

從文件中導入STDIN

使用<來重定向標準輸入

支持標準輸入的命令|

cat tr mail bc

more less head tail cut wc sort uniq grep。。。

如:

cat </etc/issue 將/etc/issue的內容作為cat命令的標準輸入

tr 'a-z' 'A-Z' </etc/issue

將/etc/issue中的小寫字符都轉換成大寫字符

tr -d abc < /etc/fstab 刪除fstab文件中的所有abc

cat > file1

將cat的標準輸出保存到file1,默認第一次回車清空,後面每次

回車都會追加寫入

cat > file1 <file2

輸入file2中的內容輸出到file1

(cat >f1 <f1,文件清空)

(cat <f1 >>f1,無限寫入)

把多行發送給STDIN

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

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

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

cat >file1 <<END

直到輸入END時,內容才會被寫入文件

mail -s nihao hello <<END

給hello發郵件,標題是nihao,以END為結束字符

實例:

tr -dc [:alpha:] < /etc/profile >ff1

將/etc/profile中內容僅保留數字和字母之後寫入ff1

tr 'a-z' 'A-Z' < /etc/motd

顯示/etc/motd,且將所有小寫字母轉化為大寫字母

tr -d ‘\r' <win.txt >win2.txt

刪除windows的txt格式文件中所有的\r(\15,0d,^M)

tr '\n' '\t' <linux.txt

將文件linux.txt中的回車轉換成tap顯示

tr ’\n' '\v' <linux.txt

將文件linux.txt中的回車轉換成垂直tap顯示

tr -d ‘\n' <linux.txt

刪除文件linux.txt中的回車鍵之後顯示

tr -s ’ ’ < ff15

顯示ff15中的信息,壓縮空格

df >df.log

將df的輸出保存至文佳df.log

tr -s ' ' < df.log

將df.log中的信息壓縮空格之後顯示

tr -s ' ' ':' < df.log

將df.log中的空格壓縮且替換成:之後顯示

tr [:lower:] [:upper:] <<END

多行轉換小寫為大寫,已END為終止符

cat > mail.to.hello

重定向將信件寫入mail.to.hello文本

mail -s nice hello < mail.to.hello

發送郵件mail.to.hello給hello,標題為nice

管道:

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

命令1 | 命令2 | 命令3 |...

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

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

最後一個名字會在當前shell進程的子shell進程中執行

組合多種工具的功能

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

將ls輸出結果中的小寫字母轉換成大寫

hostname | tr 'a-z' 'A-Z' | tr -d '.'

將hostname輸出的小寫字母換成大寫,並刪除字符'.'

cat mail.to.hello | mail -s nihao hello

使用管道發送郵件mail.to.hello給hello,標題是nihao

ls /boot /error 2>@1 | tr 'a-z' 'A-Z'

兩種寫法 |&

將ls /boot /error 的標準輸出和標準錯誤中的小寫換成大寫

ls /boot /error |& tr 'a-z' 'A-Z' | tr ' ' ':' >>f1

將ls boot /error 的標準輸出和標準錯誤中的小寫換成大寫,且將

空格換成冒號,追加保存到文件f1

df | tr -s ' ' ':'

將df命令的空格壓縮顯示換成冒號

df | tr -c ' ' ':'

將df命令的空格以外的字符換成':'顯示

df | tr -c [:alpha:] ':'

將df命令的字母以外的字符換成':'顯示

echo 1+2+3 | bc

計算1+2+3的和

echo {1..100} | tr ' ' '+' | bc

計算1-100的和

seq -s ' ' 10

生成數字1-10 中間以空格隔開

seq -s + 100 | bc

1+到100的另一種寫法

相關命令:

less:一頁頁的查看輸入

ls -l /etc | less

將ls -l /etc的結果一頁一頁的輸出

man less |less

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

echo "test email" | mail -s nihao hello

發送test email 給hello 標題為nihao

lpr:把輸入發送給打印機

echo "test print" |lpr -P printer_name

通過pingter_name 打印輸入test print

tar命令

未介紹 tar -cvf - /home | tar -xvf -

重定向到多個目標:tee

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

把命令1的STDOUT保存在文件中,作為命令2的輸入

-a 追加

使用:

保存不同階段的輸出

復雜管道的故障排除

同時查看和記錄輸出

實例:

echo "test email" |tee -a ff13| mail -s nihao hello

將“test email”保存至ff13,且作為郵件內容發送給hello 標題nihao

ls -l |tee -a ff11| tr ' ' '.'

將ll -l 的結果保留至ff11,且將空格轉化為.輸出

習題

1.將/etc/issue文件中的內容轉化為大寫後保存至/data/issue.out文件中

cat /etc/issue | tr 'a-z' 'A-Z' > /data/issue.out1

tr 'a-z' 'A-Z' < /etc/issue > /data/issue.out2

2.將當前提供登錄用戶的信息轉換為大寫後保存至/dada/who.out中

who | tr 'a-z' 'A-Z' >/data/who.out1

3.一個linux用戶給root發郵件,要求郵件標題為help,正文為隨意

[root@sentos7 /data]#mail -s help hello <<END

> Hello,i am $USER,

> The,system version is here,please help me to check it

> thanks!

> `lsb_release -a`

>END

4.將/root/下文件列表,顯示成一行,並文件名之間用空格隔開

ls /root |tr '\n' ' '

5.計算1+2...+100的總和

echo {1..100} | tr ' ' + | bc

seq -s + 100 |bc

6.刪除windows文本文件中的'^M'字符

tr -d '\r' < /root/win.txt >win1.txt

\r的其他寫法\15

7.處理字符串"xt.,l 1 jr#!$mn 2 c*/fe 3 uz 4",只保留其中的數字和空格

echo "xt.,l 1 jr#!$mn 2 c*/fe 3 uz 4" | tr -dc '[:digit:][:space:]'

8.將PATH變量每個目錄顯示在獨立的一行

echo $PATH |tr ':' '\n'

9、將指定文件中0-9分別替代成a-j

tr '0-9' 'a-j' < /etc/profile

? 10、將文件/etc/centos-release中每個單詞(由字母組成)顯示在獨立的

一行,並無空行

cat /etc/centos-release |tr -c '[:alpha:]' ' ' | tr -s ' ' '\n'

筆記整理完成時間:2018年4月3日17:24:38


第四章標準I/O和管道