LinuxShell編程五之呈現(xiàn)數(shù)據(jù)

第十五章:呈現(xiàn)數(shù)據(jù)

本章內(nèi)容

再探重定向
標(biāo)準(zhǔn)輸入和輸出
報告錯誤
丟棄錯誤
丟棄數(shù)據(jù)
創(chuàng)建日志文件

15.1 理解輸入和輸出

兩種顯示腳本輸出的方法

在顯示器屏幕上顯示輸出
將輸出重定向到文件中

15.1.1 標(biāo)準(zhǔn)文件描述符

Linux系統(tǒng)將每個對象當(dāng)做文件處理至会,這包括輸入和輸出進(jìn)程
Linux用文件描述符(file descriptor)來標(biāo)識每個文件對象
文件描述符是一個非負(fù)整數(shù),可以唯一標(biāo)識回話中打開的文件
每個進(jìn)程一次最多可以有九個文件描述符
出于特殊目的仔拟,bash shell保留了前三個文件描述符

Linux的標(biāo)準(zhǔn)文件描述符

文件描述符:縮寫:描述
0:STDIN:標(biāo)準(zhǔn)輸入
1:STDOUT:標(biāo)準(zhǔn)輸出
2:STDERR:標(biāo)準(zhǔn)錯誤

1.STDIN

STDIN文件描述符代表shell的標(biāo)準(zhǔn)輸入
對終端界面來說诵姜,標(biāo)準(zhǔn)輸入時鍵盤
shell從STDIN文件描述符對應(yīng)的鍵盤獲得輸入,在用戶輸入時處理每個字符
使用輸入重定向符號(<)時,讀取文件并能夠提取數(shù)據(jù)

使用cat命令用testfile文件中的行作為輸入

編寫testfile文件

This is first line.
This is a test line
This is third line.

執(zhí)行命令

cat < testfile

2.STDOUT

STDOUT文件描述符代表shell的標(biāo)準(zhǔn)輸出
在終端界面上工坊,標(biāo)準(zhǔn)輸出就是終端顯示器
shell的所有輸出會被定向到標(biāo)準(zhǔn)輸出中,也就是顯示器
默認(rèn)情況下敢订,大多數(shù)bash命令會將輸出導(dǎo)向STDOUT文件描述符
也可以使用輸出重定向來改變(>)

執(zhí)行命令

ls -l > test2
cat test2
who >> test2
cat test2
ls -al badfile > test3
cat test3

當(dāng)執(zhí)行一個錯誤的命令時王污,shell并未將錯誤消息重定向到文件中

3.STDERR

shell通過特殊字符的STDERR文件描述符來處理錯誤消息
STDERR文件描述符代表shell的標(biāo)準(zhǔn)錯誤輸出
shell或shell中運行的程序和腳本出錯時生成的錯誤消息都會發(fā)送到這個位置
默認(rèn)情況下,錯誤消息也會輸出到顯示器輸出中
STDERR并不會隨著STDOUT的重定向而發(fā)生改變

15.1.2 重定向錯誤

1.只重定向錯誤

STDERR文件描述符為2楚午,可以選擇只重定向錯誤消息
將文件描述符放在重定向符號前
該值必須緊緊地放在重定向符號前昭齐,否則不會生效

執(zhí)行命令

ls -al badfile 2> test4
cat test4

也可以組合使用STDOUT和STDERR

執(zhí)行命令

ls -la test badtest test2 2> test5
cat test5

2.重定向錯誤和數(shù)據(jù)

如果想重定向錯誤和正常輸出,必須用兩個重定向符號
需要在符號前面放上帶重定向數(shù)據(jù)所對應(yīng)的文件描述符
然后指向用于保持?jǐn)?shù)據(jù)的輸出文件

執(zhí)行命令

ls -al test test2 test3 badtest 2> test6 1>test7
cat test6
cat test7

使用特殊符號(&>)將STDOUT和STDERR的輸出重定向到同一個輸出文件

執(zhí)行命令

ls -al test test2 test3 badtest &>test7
cat test7

15.2 在腳本中重定向輸出

15.2.1 臨時重定向

命令演示:echo "This is an error message" >&2
命令說明:手動生成錯誤信息并輸出重定向到STDERR

編寫test8.sh腳本

#!/bin/bash
echo "This is an error" >&2
echo "This is normal output"

執(zhí)行命令

./test8.sh
./test8.sh 2>test9
cat test9

15.2.2 永久重定向

使用exec命令告訴shell在腳本執(zhí)行期間重定向某個特定文件描述符

編寫test10.sh腳本

#!/bin/bash
exec 1>testout

echo "This is a test of redirecting all output"
echo "from a script to another file"
echo "without having to redirect every individual line"

執(zhí)行命令

./test10.sh
cat testout

也可以在腳本執(zhí)行過程中重定向STDOUT

編寫test11.sh腳本

#!/bin/bash
exec 2>testerror

echo "this is the start of the script"
echo "now redirecting all output to another location"

exec 1>testout

echo "Theis out should go to the testout file"
echo "but this should go to testerror file" >&2

執(zhí)行命令

./test11.sh
cat testout
cat testerror

15.3 在腳本中重定向輸入

命令演示:exec 0< testfile
命令說明:使用與腳本重定向STDOUT和STDERR相同的方法將STDIN從鍵盤重定向到其他位置

編寫test12.sh腳本

#!/bin/bash
exec 0< testfile
count=1

while read line
do
    echo "Line #$count:$line"
    count=$[ $count + 1 ]
done

15.4 創(chuàng)建自己的重定向

在腳本中重定向輸入和輸出時矾柜,并不局限這3個默認(rèn)的文件描述符
在shell中最多可以有9個打開的文件描述符
可以將其他6個從3~8的文件描述符中的任意一個分配給文件

15.4.1 創(chuàng)建輸出文件描述符

使用exec命令來給輸出分配文件描述符

編寫test13.sh腳本

#!/bin/bash

exec 3>test13out

echo "This should display on the monitor"
echo "and this should be stored in the file" >&3
echo "Then this should be back on the monitor"

執(zhí)行命令

./test13.sh
cat test13out

命令演示:exec 3>>test13out
命令說明:使用exec命令來講輸出追加到現(xiàn)有文件中

15.4.2 重定向文件描述符

在腳本中臨時重定向輸出阱驾,然后恢復(fù)默認(rèn)輸出設(shè)置

編寫test14.sh腳本

#!/bin/bash

exec 3>&1
exec 1>test14out

echo "This should store in the output file"
echo "along with whis line"

exec 1>&3

echo "Now things should be back normal"

執(zhí)行命令

./test14.sh
cat test14out

這個例子有點叫人抓狂就谜,來一段一段地看。首先里覆,腳本將文件描述符 3 重定向到文件描述符1
的當(dāng)前位置丧荐,也就是 STDOUT 。這意味著任何發(fā)送給文件描述符 3 的輸出都將出現(xiàn)在顯示器上喧枷。
第二個 exec 命令將 STDOUT 重定向到文件虹统,shell現(xiàn)在會將發(fā)送給 STDOUT 的輸出直接重定向到
輸出文件中。但是隧甚,文件描述符 3 仍然指向 STDOUT 原來的位置车荔,也就是顯示器。如果此時將輸出
數(shù)據(jù)發(fā)送給文件描述符 3 戚扳,它仍然會出現(xiàn)在顯示器上忧便,盡管 STDOUT 已經(jīng)被重定向了。
在向 STDOUT (現(xiàn)在指向一個文件)發(fā)送一些輸出之后咖城,腳本將 STDOUT 重定向到文件描述符
3 的當(dāng)前位置(現(xiàn)在仍然是顯示器)茬腿。這意味著現(xiàn)在 STDOUT 又指向了它原來的位置:顯示器。
這個方法可能有點叫人困惑宜雀,但這是一種在腳本中臨時重定向輸出切平,然后恢復(fù)默認(rèn)輸出設(shè)置
的常用方法。

15.4.3 創(chuàng)建輸入文件描述符

可以將STDIN文件描述符保存到另外一個文件描述符辐董,然后在讀取完文件之后再將STDIN恢復(fù)到它原來的位置

編寫test15.sh腳本

#!/bin/bash

exec 6<&0
exec 0< testfile

count=1
while read line
do
    echo "Line #$count:$line"
    count=$[ $count+1 ]
done

exec 0<&6
read -p "Are you done now [Y/N]?" answer
case $answer in
Y|y) echo "Goodbye" ;;
N|n) echo "Sorry,this is the end."
esac

15.4.4 創(chuàng)建讀寫文件描述符

可以用同一個文件描述符對同一個文件進(jìn)行讀寫
在對同一個文件進(jìn)行數(shù)據(jù)讀寫時悴品,shell會維護(hù)一個內(nèi)部指針
任何讀或?qū)懚紩闹羔樕洗蔚奈恢瞄_始

編寫test16.sh腳本

#!/bin/bash

exec 3<> testfile
read line <&3
echo "Read: $line"
echo "This is a test line" >&3

testfile內(nèi)容

This is the first line.
This is the second line.
This is the third line.

執(zhí)行命令

cat testfile
./test16.sh
cat testfile

15.4.5 關(guān)閉文件描述符

命令格式:exec 3>&-
命令說明:在腳本結(jié)束前手動關(guān)閉文件描述符,將它重定向到特殊符號&-

在關(guān)閉文件描述符時简烘,如果隨后在腳本中打開了同一個輸出文件苔严,則會覆蓋已有文件

編寫test17.sh腳本

#!/bin/bash

exec 3> test17file
echo "This is a test line of data" >&3
exec 3>&-

cat test17file

exec 3> test17file
echo "This'll be bad" >&3

執(zhí)行命令

./test17.sh
cat test17file

15.5 列出打開的文件描述符

使用lsof命令顯示已打開的文件描述符

編寫test18.sh腳本

#!/bin/bash

exec 3> test18file1
exec 6> test18file2
exec 7< testfile

/usr/bin/lsof -a -p $$ -d0,1,2,6,7

15.6 阻止命令輸出

可以將STDERR重定向到null文件的特殊文件
在Linux系統(tǒng)上null文件的標(biāo)準(zhǔn)位置時/dev/null
重定向到該位置的任何數(shù)據(jù)都會被丟掉
通常用于清除日志文件

命令演示:cat /dev/null > testfile
命令說明:清除testfile文件中的數(shù)據(jù)

15.7 創(chuàng)建臨時文件

15.7.1 創(chuàng)建本地臨時文件

命令演示:mktemp testing.XXXXXX
命令說明:mktemp命令創(chuàng)建一個臨時文件,會自動用6個字符碼替換這6個X孤澎,從而保證文件名在目錄中是唯一的届氢。且可以創(chuàng)建多個臨時文件,每個文件都是唯一的覆旭。

編寫test19.sh腳本

#!/bin/bash

tempfile=$(mktemp test19.XXXXXX)

exec 3>$tempfile

echo "This script writes to temp file $tempfile"

echo "This is the first line" >&3
echo "This is the second line" >&3
echo "This is the last line" >&3

exec 3>&-

echo "Done creating temp file.The contents are:"
cat $tempfile
rm -f $tempfile 2> /dev/null

執(zhí)行命令

./test19.sh
ls -al test19*

15.7.2 在/tmp目錄創(chuàng)建臨時文件

使用-t選項強(qiáng)制mktemp命令在系統(tǒng)的臨時目錄下創(chuàng)建該文件
mktemp命令會返回該臨時文件的全路徑

編寫test20.sh腳本

#!/bin/bash

tempfile=$(mktemp -t tmp.XXXXXX)

echo "This is a test file." > $tempfile
echo "This is the second line of the test." >> $tempfile
echo "The temp file is located at: $tempfile"

cat $tempfile
rm -f $tempfile

15.7.3 創(chuàng)建臨時目錄

使用-d選項告訴mktemp命令創(chuàng)建一個臨時目錄

編寫test21.sh腳本

#!/bin/bash

tempdir=$(mktemp -d dir.XXXXXX)
cd $tempdir
tempfile1=$(mktemp temp.XXXXXX)
tempfile2=$(mktemp temp.XXXXXX)
exec 7> $tempfile1
exec 8> $tempfile2

echo "Sending data to directory $tempdir"
echo "This is a test line of data for $tempfile1" >&7
echo "This is a test line of data for $tempfile2" >&8

執(zhí)行命令

./test21.sh
ls -al
ls -al dir.zKQTCL/
cat dir.zKQTCL/temp.EZBifQ
cat dir.zKQTCL/temp.sO4oa4

15.8 記錄消息

將輸出同時發(fā)送到顯示器和日志文件
使用tee命令退子,相當(dāng)于管道的一個T型接頭
將從STDIN過來的數(shù)據(jù)同時發(fā)往兩處
一處是STDOUT,另一處時tee命令所指定的文件名:tee filename

使用-a選項將數(shù)據(jù)追加到文件中型将,數(shù)據(jù)顯示在屏幕上的同時再永久保存在文件中

編寫test22.sh腳本

#!/bin/bash

tempfile=test22file

echo "This is the start of the test" | tee $tempfile
echo "This is the second line of the test" | tee -a $tempfile
echo "This is the end of the test" | tee -a $tempfile

執(zhí)行命令

./test22.sh
cat test22file

15.9 實例

案例說明:文件重定向常見于腳本需要讀入文件和輸出文件寂祥。通過讀取.csv格式的數(shù)據(jù)文件,輸出SQL INSERT語句來將數(shù)據(jù)插入數(shù)據(jù)庫

編寫members.csv文本

Blum,Richard,123 Main st.,Chicago,IL,60601
Blum,Barbara,123 Main st.,Chicago,IL,60601
Bresnahan,Christine,456 Oak Ave.,Columbus,OH,43201
Bresnahan,Timothy,456 Oak Ave.,Columbus,OH,43201

編寫test23.sh腳本

#!/bin/bash

outfile='members.sql'
IFS=','

while read lname fname address city state zip in ${1}
do
    cat >> $outfile << EOF
    INSERT INTO members (lname,fname,address,city,state,zip) 
    VALUES('$lname','$fname','$address','$city','$state','$zip');
EOF
done

執(zhí)行命令

./test23.sh < members.csv
cat members.sql

15.10 小結(jié)

bash shell允許在腳本中創(chuàng)建自己的文件描述符七兜。使用mktemp可以很方便的創(chuàng)建臨時目錄及文件丸凭。tee命令便于將輸出同時發(fā)送給標(biāo)準(zhǔn)輸出和日志文件。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市惜犀,隨后出現(xiàn)的幾起案子铛碑,更是在濱河造成了極大的恐慌,老刑警劉巖虽界,帶你破解...
    沈念sama閱讀 218,525評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件亚茬,死亡現(xiàn)場離奇詭異,居然都是意外死亡浓恳,警方通過查閱死者的電腦和手機(jī)刹缝,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,203評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來颈将,“玉大人梢夯,你說我怎么就攤上這事∏缁” “怎么了颂砸?”我有些...
    開封第一講書人閱讀 164,862評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長死姚。 經(jīng)常有香客問我人乓,道長,這世上最難降的妖魔是什么都毒? 我笑而不...
    開封第一講書人閱讀 58,728評論 1 294
  • 正文 為了忘掉前任色罚,我火速辦了婚禮,結(jié)果婚禮上账劲,老公的妹妹穿的比我還像新娘戳护。我一直安慰自己,他們只是感情好瀑焦,可當(dāng)我...
    茶點故事閱讀 67,743評論 6 392
  • 文/花漫 我一把揭開白布腌且。 她就那樣靜靜地躺著,像睡著了一般榛瓮。 火紅的嫁衣襯著肌膚如雪铺董。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,590評論 1 305
  • 那天禀晓,我揣著相機(jī)與錄音精续,去河邊找鬼。 笑死匆绣,一個胖子當(dāng)著我的面吹牛驻右,可吹牛的內(nèi)容都是我干的什黑。 我是一名探鬼主播崎淳,決...
    沈念sama閱讀 40,330評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼愕把!你這毒婦竟也來了拣凹?” 一聲冷哼從身側(cè)響起森爽,我...
    開封第一講書人閱讀 39,244評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎嚣镜,沒想到半個月后爬迟,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,693評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡菊匿,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,885評論 3 336
  • 正文 我和宋清朗相戀三年付呕,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片跌捆。...
    茶點故事閱讀 40,001評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡徽职,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出佩厚,到底是詐尸還是另有隱情姆钉,我是刑警寧澤,帶...
    沈念sama閱讀 35,723評論 5 346
  • 正文 年R本政府宣布抄瓦,位于F島的核電站潮瓶,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏钙姊。R本人自食惡果不足惜毯辅,卻給世界環(huán)境...
    茶點故事閱讀 41,343評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望煞额。 院中可真熱鬧悉罕,春花似錦、人聲如沸立镶。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,919評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽媚媒。三九已至嗜逻,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間缭召,已是汗流浹背栈顷。 一陣腳步聲響...
    開封第一講書人閱讀 33,042評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留嵌巷,地道東北人萄凤。 一個月前我還...
    沈念sama閱讀 48,191評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像搪哪,于是被迫代替她去往敵國和親靡努。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,955評論 2 355

推薦閱讀更多精彩內(nèi)容

  • 一、Python簡介和環(huán)境搭建以及pip的安裝 4課時實驗課主要內(nèi)容 【Python簡介】: Python 是一個...
    _小老虎_閱讀 5,746評論 0 10
  • 官網(wǎng) 中文版本 好的網(wǎng)站 Content-type: text/htmlBASH Section: User ...
    不排版閱讀 4,383評論 0 5
  • .bat腳本基本命令語法 目錄 批處理的常見命令(未列舉的命令還比較多惑朦,請查閱幫助信息) 1兽泄、REM 和 :: 2...
    慶慶慶慶慶閱讀 8,100評論 1 19
  • linux資料總章2.1 1.0寫的不好抱歉 但是2.0已經(jīng)改了很多 但是錯誤還是無法避免 以后資料會慢慢更新 大...
    數(shù)據(jù)革命閱讀 12,168評論 2 33
  • 一周前還覺得五公里是個遙不可及的距離病梢,今天自己已經(jīng)堅持跑了四個五公里! 還記得自己跑第一個五公里的情景梁肿,跑前心中忐...
    木子晨星閱讀 214評論 0 0