首頁  >  文章  >  運維  >  輸入輸出,重定向,管道的實例介紹

輸入輸出,重定向,管道的實例介紹

零下一度
零下一度原創
2017-06-30 15:49:422904瀏覽
1、輸入輸出,重定向,管道
2、<(cmd);>(cmd)
3、>;<;>>;<<;>>>;<<<
4、文本处理_1:cat;head;tail;cut;wc;sort;uniq;tr;tac;rev
 
 
一、輸入輸出,重定向,管道
1、Linux 程序有三个标准的输入输出,分别是:
标准输入,用数字0表示,默认连接到键盘,程序通常用来获取用户的输入
标准输出,用数字1表示,默认连接到屏幕,程序通常用来输出信息
标准错误,用数字2表示,默认连接到屏幕,程序通常用来输出错误信息
解析:
命令 passwd 从标准输入读取用户密码,所以用户可以用键盘输入密码
命令 echo 把结果输出到标准输出,所以可以在屏幕上看到结果
普通用户没有权限查看/root 目录,所以出错,于是 ls 把错误信息输出到标准错误,也就是屏幕
2、> 与 >>
> 删除原来数据,写入新数据
>> 将新数据追加到原来数据之后
3、/dev/null
俗称:垃圾桶文件
# echo hello world > /dev/null --重定向到该文件的数据都被内核丢掉了,可以用这个特性来屏蔽某些输出信息
# ls / /root 2> /dev/null --屏蔽掉命令的出错信息
4、输出重定向
用户可以根据需要,把默认的输入输出的方向进行修改
# ls -l > test
# ls -l 1> test --两条都是标准输出重定向到 test 文件,即默认1可省略
# ls /jjjj 2> test --将标准错误重定向到 test 文件
# ls / /jjjj 1> stdout 2> stderr --将标准输出与标准错误分别重定向到两个不同的文件中
# ls /jjjj / > std 2>&1 --將標準錯誤合併到標準輸出,並重定向到一個檔案當中
# ls /jjjj / &> std --結果與上條語句等價,更簡潔
# ls /jjjj / &>> std --也是將標準輸出與標準錯誤重定向追加到一個檔案
5、標準輸入重定向
  # cat 0< /etc/passwd
  # cat < /etc/passwd
  # cat /etc/passwd --cat指令的wd
  # cat /etc/passwd --cat指令的標準輸入來自檔案/etc/passwd 中
6、管道
上面所描述的重定向,就是把標準的輸入輸出連接到檔案。 我們也可以把多個程式之間的標準輸入輸出進行連接,實現命令之間資料的傳遞,這種技術被形像地稱做管道,程式的輸出就像流水在管道中流通一樣,從最左邊的程式流到最右邊的程式。管道是linux shell 裡非常常見的技術,利用管道技術可以達到配合使用多個小工具,完成非常複雜且強大的功能。
# cat /etc/passwd | head -n 3 --左邊的指令的標準輸出作為右邊的指令的標準輸入
# cat /etc/passwd | head -n 3 | tail -n 1
7、標準輸入輸出的深入探討
標準的輸入輸出是Linux 預設為程式創造好的三個文件描述符,雖然大多數的程式都會使用這三個文件描述符來作為自己的輸入輸出,但是這並非是強制性的,也就是說,程式可以不使用這三個標準的文件描述符,而是自己開啟新的檔案描述符來使用。當程式不使用標準的輸入輸出時,這裡所使用的重定向對其也就不起作用了。
例如:
passwd: 程式從標準輸入讀取使用者密碼,因此我們可以透過重定向標準輸入來提供它密碼
ssh: 命令是用於遠端登入的程序,它讀取使用者輸入的密碼時,使用的不是標準輸入,因此我們不能透過重定向標準輸入來向它提供密碼
#8、驗證進程的標準輸入輸出所連接的檔案
# sleep 999 1> /tmp/good 2>&1 --在一個終端執行指令
# pgrep -x sleep --在另一個終端,找出sleep 的進程ID
# lsof -anop 16715 -d 0,1,2 --查看該進程所開啟的檔案
9、驗證重定向發生的時機
# vim file
# cat -n file > file --期待cat 會在每一行前面加上行號,然後把結果重定向保存回原來的檔案file 中
#### cat file --為空了###
原因:shell 執行指令之前,會先執行重定向操作,在第 2 個指令中,先執行 > file,這個重定向操作會把檔案file 的內容清空。當重定向操作把file 文件清空之後,再cat 該文件,自然就看不到任何內容了
$ sudo ls /root > /root/ls.log --這個例子中,用戶沒有機會輸入密碼,因為重定向操作先執行,當前用戶是普通用戶,無法在路徑/root/ls.log 中建立文件,shell 出錯並退出:bash: /root/ls.log: Permission denied。此時還沒有執行指令sudo,所以也就沒有機會輸入密碼
 
#二、<(cmd);>(cmd)
#1、<(cmd)
用進程置換的方式重定向標準輸入
2、>(cmd)
以進程置換的方式重定向標準輸出
3、進程置換
進程的標準輸出存到一個暫存檔案中,返回暫存文件的路徑<(),當需要使用程式的輸出,但是又不想產生一個中間檔案時,可以考慮使用行程置換
# paste <(seq $(wc -l /etc/passwd | cut -d" " -f1)) <(awk -F: '{print $1}' /etc/passwd)
# paste <(seq 26) <(awk -F: '{ print $1}' /etc/passwd) --可將該兩個指令進行比較
 
三、>;<;>>;<< ;;>>>;<<<
#1、> --輸出重定向,建立(存在則覆寫)
# echo 'hello world' > test -- 不存在test 則創建,存在則覆蓋裡面內容
2、< --輸入重定向,來自檔案
# less < /etc/passwd --將/etc/passwd 裡面的內容輸入到工具less
# cat < <(ls /) --這裡使用到指令置換
# wc -l < $(echo /etc/passwd)
# wc -l < <(cat /etc/passwd) --這裡使用到進程置換
3、>> --重定向到文件,創建(存在則添加到文件末尾)
# echo 'hello george' >> george - - 不存在george 則創建,存在則追加內容至文件末尾
4、<< --重定向,用於Here document
################################################ 4.1、Here Document #########是在Linux Shell 中的一種###特殊的重定向方式,它的基本的形式如下:######
cmd << delimiter
Here Document Content
delimiter
: << delimiter --shell批次註解
#Here Document Content
delimiter
功能:將兩個delimiter 之間的內容(Here Document Content) 傳遞給cmd 作為輸入參數
# 4.2、終端機
# cat << EOF
> one
> two
#> ; three
> EOF
EOF --只是一個標識而已,可以替換成任意的合法字元
> - -這個符號是終端產生的提示輸入訊息的標識符
delimiter -- 一定要頂格寫,前面後面不能有任何字符,包括空格
4.3、shell
# vim here.sh --註:裡面還可以使用變數
!/bin/bash
cat << EOF > output.sh
echo "hello"
echo "world"
echo $1
# EOF
# chmod a+x here.sh
# ./here.sh george
# cat output.sh --查看裡面內容;在這裡$1 被展開成為了腳本的參數
注意:若不想展開這個變量,則需使用雙引號將第一個EOF 引起來。
4.4、<<-
Here Document 還有一個用法就是將'<<' 變成'< <-'。 使用<<- 的唯一變化就是Here Document 的內容部分每行前面的tab (製表符)將會被刪除掉,這種用法是為了編寫Here Document的時候可以將內容部分進行縮進,方便閱讀程式碼
5、<<< --重定向,用於Here string
# wc -l <<< "$( ls -l /home)"
# while read x; do echo "hello";done <<< "$(seq 5)"
# bc <<< "2 ^ 10"
# vim string.sh
#!/bin/bash
while read line
do
if [ "${line#ftp:}" != "$line" ];then
awk -F: '{print $6}' <<< $line
break
fi
done < /etc/passwd
注释:循环读取/etc/passwd 文件中的每一行,如果是ftp 用户,就打印出其家目录,并退出循环
${line#ftp:}:某行开头匹配到了 ftp: ;则只取该行未匹配部分
# chmod a+x string.sh
# ./string.sh
 
四、文本处理_1:cat;head;tail;cut;wc;sort;uniq;tr;tac;rev
文本处理是每一个系统管理员都会频繁接触的任务,其核心内容是相关工具的使用,关键要点在于灵活地结合多个工具去完成任务
1、cat --concatinate,把一个或者多个文件的內容按順序連接起來,輸出到标准輸出
# cat -n /etc/passwd --显示文件内容,并且加上行号
# cat -A /etc/passwd --打印出一些不可见的字符和位置标记
# cat 1.txt 2.txt > test.txt --合并文件
2、head --读取文件头部
# head -n 3 /etc/passwd --读取文件/etc/passwd 的前面三行
# head -n -1 file --丢弃 file 的最后一行
# head -c 3 /etc/passwd --读取文件/etc/passwd 的前面三個字节
# head -c -3 file --丢弃 file 的最后 3 个字节
# head -c 10m /dev/urandom > big --创建一个10M的文件
3、tail --读取文件尾部
# tail -n 3 /etc/passwd --读取文件 /etc/passwd 后面三行
# tail -n +28 /etc/passwd --从第28行开始读取,直到文件尾部;丢弃头部的27行
# tail -c 3 /etc/passwd --读取文件 /etc/passwd 的后面三個字节
# tail -c +28 /etc/passwd --从第28字节开始读取,直到文件尾部;丢弃头部的27字节
# tail -f /etc/passwd --跟踪文件尾部内容的变化,常用來视察日志文件的变化化,非常实用
4、cut --功能类似于awk,但是没有awk那么强大和复杂,当要对数据做分列输出时,经常使用awk,用cut的时候不多
常用选项:
-d --定义分隔符
-b --输出指定位置的字节(byte)
-c --输出指定位置的字符(character)
# echo "a;b;c d;e" | cut -d ";" -f1,3,4 -- -d 定义分隔符( 默认是 TAB );-f 定义输出对应字段
# cat -n /etc/passwd | cut -d $'\n' -f1,3-5,7 -- 使用换行符做分隔符
# echo 我是中国人 | cut -b1-3 -- -b 输出指定位置的字节(byte);一个utf8 的中文字占用3个字节
# echo 我是中国人 | cut -c2-4 -- -c 输出指定位置的字符(character);与-b 的区别表现在处理非英文字符时
# echo 做个勇敢的中国人 | cut -b1-2,9 --会输出一个 ”假“ 字
# echo -n 做个勇敢的中国人 | xxd --会发现 1,2,9 这三个字节为:e581 87
# echo -n 假 | xxd --而 ”假“ 也是
5、wc --计算数据的字节数,字符数,单词数,行数
常用选项:
-c --计算字节数
-m --计算字符数
-w --计算词数
-l --计算行数
# echo -n 我是中国人 | wc -c -- -c 计算字节数,5个utf8中文占15个字节
# echo -n 我是中国人 | wc -m -- -m 计算字符数,与-c 的区别表现在处理非英文字符时,类似于命令cut
# echo -n 我是中国人 | wc -w -- -w 计算词数,没有分割符分开,5个中文算一个词,这与中文所谓的“词”是不同的
# echo -n Uppercase CHINESE | wc -w --两个词
# echo -n Uppercase CHINESE | wc -c --17个英文字节,没有 -n 就有18个(因为还有一个换行符)
# echo -n Uppercase CHINESE | wc -m --17個英文字符,沒有-n 就有18個(因為還有一個換行符)
# wc -l /etc/passwd - - -l 計算行數
6、sort --依行對檔案進行排序
常用選項:
##-t --指定分割符
-k --指定排序的欄位
-u --移除重複的行
-n, -h --依照數值排序
-r --反過來排序
# cut -d ":" -f7 /etc/passwd | sort -u -- -u 移除重複行
# echo -e "1\n2\n10" | sort
# echo -e "1\n2\n10" | sort -n -- -n 依數值排序,無法處理K, M, G 等單位字元
# ls -lh | tail -n +2 | sort -k5,5n -- -k 指定排序的欄位
# ls -lh | tail -n +2 | sort -k5,5h -- -h 依照數值排序時,能處理K, M, G 等單位字元
# head -4 /etc/passwd | sort -t: -k7,7
-- -t 以冒號: 作為欄位分割符,按第7字段排序
# head -4 /etc/passwd | sort -t: -k7,7 -k3,3n --先按第7字段排序,若第7字段有相同的,則依第3欄位排序
# echo -e "1\n2\n3" | sort -nr -- -r 對排序反轉
# head -4 /etc/passwd | sort -t: -k7,7 -k3,3nr --至反轉第3字段排序,也可同時對兩個字段反轉
7、uniq --去除連續的重複行
常用選項:
-c --計算重複行的數字
# echo -e "1 \n1\n2\n1" | uniq -- 結果中仍有兩個1,因為這兩個1是不連續的
# echo -e "1\n1\n2\n1" | sort - u -- sort 移除重複則不用連續
# cut -d: -f7 /etc/passwd | sort | uniq -c -- 在sort指令範例的基礎上,計算不同的登入shell出現的次數
8、tr --轉換,刪除,縮減相同字元
#常用選項:
-d --刪除,刪除所有符合的字母
#########-s --縮減,縮減相同字元######
格式: tr SET1 SET2
注意: 把集合1裡面的字元轉換成集合2中對應位置的字符,所以原則上兩個集合中的字符數目應該相同,不過,如果兩個集合中的字元數不相等,程式也不會出錯,請留心這種情況下的結果。 重點:
a、tr 不關心兩個集合中是什麼字符,它只是簡單地把對應位置的字符逐一做替換而已、
# b、 tr 做的是單字的替換,不能替換字串
# echo abc | tr a-z A-Z --把26個小寫字母轉換成相對應的大寫字母
## echo abc | tr ab BA --把a 和b,分別轉換成B 和A
# echo 好人做好事| tr 好壞-- 「好」 轉換成「壞」
# echo abcdefg | tr a-z AB --集合2較短,程式自動用集合2中最後一個字元來擴充集合2
# echo abcdefg | tr a-b A-Z --集合2較長,程式自動把集合2切短
# echo Abc | tr a-zA-Z A-Za-z --實現英文字母大小反轉
# echo hello world | tr -d ow -- -d 刪除,所有符合的字母
# echo 0123456789 | tr -d 13579
# tr -d '\012' < /etc/passwd -- 刪除檔案/etc/passwd 中的換行符,tr 可用八進位表示一個字元
# echo aabbaacc | tr -s a -- -s,將每個連在一起的幾個a 縮減至一個
# echo aabbaacc | tr -s a A -- 集合之後再做轉換
#9、tac --把一個或多個檔案的內容依序連接起來,輸出到標準輸出,在每個文件中,內容以行號反序列印
# echo -e "111111111\n2222222" > f1
# echo -e "3333333333\n4444444" > f2
# tac f2 f1
10、rev --把檔案中的行左右反轉
# echo -e "1234567\nabcdefg " > test
# rev test
 
#五、擴充功能
##1、cat,md5sum
# echo file1 > file1
# echo file2 > file2 --建立兩個檔案
# md5sum file1 file2 --比較他們的md5 值是否相同
# head -c 10m /dev/urandom > bigfile --使用隨機裝置建立一個10M 的檔案
# head -c 3m bigfile > file1 --將前3M 資料導入file1
# tail -c 4m bigfile > file3 --將後3M 資料導入file3
## head -c 6m bigfile | tail -c 3m > file2 --將中間4M 資料導入file2
# ls -lh file*
# cat file1 file2 file3 > newbigfile --使用cat 將三個檔案合併到一個新大檔案
# md5sum newbigfile bigfile --在用指令比較舊大檔案與新大檔案的md5sum 值

以上是輸入輸出,重定向,管道的實例介紹的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn