1. 程式人生 > >Linux-標準IO和管道

Linux-標準IO和管道

IO重定向 管道

技術分享圖片

打開的文件都有一個fdfile description(文件描述符)

[root@centos7 data]#exec 8<>/data/hosts

[root@centos7 data]#ll /proc/$$/fd

total 0

lrwx------. 1 root root 64 Mar 30 14:22 0 -> /dev/pts/3

lrwx------. 1 root root 64 Mar 30 14:22 1 -> /dev/pts/3

lrwx------. 1 root root 64 Mar 30 14:22 2 -> /dev/pts/3

lrwx------. 1 root root 64 Mar 30 16:58 255 -> /dev/pts/3

lrwx------. 1 root root 64 Mar 30 17:17 8 -> /data/hosts

[root@centos7 data]#cat /proc/$$/fd/8

127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4

::1 localhost localhost.localdomain localhost6 localhost6.localdomain6

其實就是軟鏈接

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

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

?標準輸出(STDOUT

)-1 默認輸出到終端窗口

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

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

標準輸出重定向:>,或者1>

ls > /dev/pts/5

ls > /data/ls.out

標準錯誤重定向:2>

追加不覆蓋:>>

對的和錯的分別重定向

ls /error /data >>/data/f1 2>>/data/f2

對的和錯的放在一起

ls /error /data >all.log 2>&1

註意次序!

新寫法:

ls /error /data &>all.log

(ls /error /data 2>&1)>all.log

set -C 不允許覆蓋,但允許追加

|> 強制覆蓋

set+C 允許覆蓋

/dev/null 垃圾箱,無底洞,不希望輸出和保存的數據可導到這裏

cat 啥都不跟的話會回顯,就既有標準輸入,又有標準輸出


tr命令

tr 轉換和刪除字符

tr [OPTION]... SET1 [SET2]

選項:

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

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

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

-t --truncate-set1:將第一個字符集對應字符轉化為第二字符集對應的字符[root@centos7 data]#tr 'a-z' 'A-Z'

asdf1234

ASDF1234

[root@centos7 ~]#tr 'a-z' 'A-Z' < anaconda-ks.cfg > /data/log

[root@centos7 ~]#cat /data/log

[root@centos7 doc]#tr -dc 'abc'

23423aabc3sff

aabc

[root@centos7 doc]#tr -s "abc"

aaabbbacde

abacde

[root@centos7 data]#hexdump -C win.txt

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

00000007

[root@centos7 data]#tr -d '\15' < win.txt >win2.txt

[root@centos7 data]#hexdump -C win2.txt

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

00000005

[root@centos7 data]#tr -d '\r' < win.txt >win3.txt

[root@centos7 data]#hexdump -C win3.txt

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

00000005

[root@centos7 data]#cat win3.txt

a b c

[root@centos7 data]#tr -s ' ' <win3.txt

a b c

[root@centos7 data]#df > df.log

[root@centos7 data]#tr -s ' ' : < df.log

Filesystem:1K-blocks:Used:Available:Use%:Mounted:on

/dev/sda2:51474912:3405572:45431516:7%:/

devtmpfs:523248:0:523248:0%:/dev

tmpfs:537748:0:537748:0%:/dev/shm

tmpfs:537748:14544:523204:3%:/run

tmpfs:537748:0:537748:0%:/sys/fs/cgroup

/dev/sda1:999320:130824:799684:15%:/boot

/dev/sda3:20511312:45420:19400932:1%:/data

tmpfs:107552:12:107540:1%:/run/user/42

tmpfs:107552:0:107552:0%:/run/user/0

/dev/sr0:8490330:8490330:0:100%:/mnt

[root@centos7 qjy]#echo abcdef | tr 'abcd' 'xyz'

xyzzef

[root@centos7 qjy]#echo abcdef | tr -t 'abcd' 'xyz'

xyzdef

多行重定向

mail [-s] "hello" [email protected] << EOF

EOF

mail [-s] "hello" [email protected] < mail.txt

郵件裏可用命令,如`hostname`

管道

cat mail.txt | mail -s 'hello' root

| 管道只處理標準輸出STDOUT,不處理STDERR,所以要想處理錯誤信息的話要重定向錯誤成標準輸出:

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

或新寫法:

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

比較老的系統如RHEL 5.4等可能不支持'

例:計算從1+2+..+100

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

seq -s + 100 | bc

也可用循環

less :一頁一頁地查看輸入

ls -l /etc | less

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

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

lpr:把輸入發送給打印機

echo "test print" | lpr -P printer_name

管道中-符號

示例:

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

tar -cvf - /home | tar -xvf -

重定向到多個目標(tee

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

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

-a 追加

使用:

?保存不同階段的輸出

?復雜管道的故障排除

?同時查看和記錄輸出

練習:

1、處理字符串“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 'a-z '

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

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

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

答:tr '0-9' 'a-j' < a.txt > a.txt

4、將文件/etc/centos-release中每個單詞(由字母組成)顯示在獨立的一行,並無空行

答:[root@centos7 ~]#cat /etc/centos-release | tr -dc '[:alpha:] ' | tr -s ' ' '\n'

CentOS

Linux

release

Core

例:創建隨機小寫字母文件名

[root@centos7 data]#touch `openssl rand -base64 12 | tr -dc '[:lower:]'`

思考:以下4項哪一項是與眾不同的?

A cmd > log 2>&1

B cmd 2>&1 > log

C cmd &> log

D cmd 2>log >&2

答案:B


Linux-標準IO和管道