第二十七課 LinuxShell編程五之呈現(xiàn)數(shù)據(jù)

說明:本文部分內(nèi)容均摘取自書籍《Linux命令行與shell腳本編程大全》婚瓜,版權(quán)歸原作者所有∨跏椋《Linux命令行與shell腳本編程大全》(第三版)第十五章學(xué)習(xí)總結(jié)

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

本章內(nèi)容

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

15.1 理解輸入和輸出

兩種顯示腳本輸出的方法

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

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

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

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

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

1.STDIN

STDIN文件描述符代表shell的標(biāo)準(zhǔn)輸入
對(duì)終端界面來說,標(biāo)準(zhǔn)輸入時(shí)鍵盤
shell從STDIN文件描述符對(duì)應(yīng)的鍵盤獲得輸入鸥跟,在用戶輸入時(shí)處理每個(gè)字符
使用輸入重定向符號(hào)(<)時(shí)等脂,讀取文件并能夠提取數(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的所有輸出會(huì)被定向到標(biāo)準(zhǔn)輸出中,也就是顯示器
默認(rèn)情況下耕皮,大多數(shù)bash命令會(huì)將輸出導(dǎo)向STDOUT文件描述符
也可以使用輸出重定向來改變(>)

執(zhí)行命令

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

當(dāng)執(zhí)行一個(gè)錯(cuò)誤的命令時(shí)苦锨,shell并未將錯(cuò)誤消息重定向到文件中

3.STDERR

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

15.1.2 重定向錯(cuò)誤

1.只重定向錯(cuò)誤

STDERR文件描述符為2,可以選擇只重定向錯(cuò)誤消息
將文件描述符放在重定向符號(hào)前
該值必須緊緊地放在重定向符號(hào)前仅胞,否則不會(huì)生效

執(zhí)行命令

ls -al badfile 2> test4
cat test4

也可以組合使用STDOUT和STDERR

執(zhí)行命令

ls -la test badtest test2 2> test5
cat test5

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

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

執(zhí)行命令

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

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

執(zhí)行命令

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

15.2 在腳本中重定向輸出

15.2.1 臨時(shí)重定向

命令演示:echo "This is an error message" >&2
命令說明:手動(dòng)生成錯(cuò)誤信息并輸出重定向到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í)行期間重定向某個(gè)特定文件描述符

編寫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)建自己的重定向

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

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 重定向文件描述符

在腳本中臨時(shí)重定向輸出埃撵,然后恢復(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

這個(gè)例子有點(diǎn)叫人抓狂赵颅,來一段一段地看。首先暂刘,腳本將文件描述符 3 重定向到文件描述符1
的當(dāng)前位置饺谬,也就是 STDOUT 。這意味著任何發(fā)送給文件描述符 3 的輸出都將出現(xiàn)在顯示器上谣拣。
第二個(gè) exec 命令將 STDOUT 重定向到文件募寨,shell現(xiàn)在會(huì)將發(fā)送給 STDOUT 的輸出直接重定向到
輸出文件中。但是森缠,文件描述符 3 仍然指向 STDOUT 原來的位置拔鹰,也就是顯示器。如果此時(shí)將輸出
數(shù)據(jù)發(fā)送給文件描述符 3 辅鲸,它仍然會(huì)出現(xiàn)在顯示器上格郁,盡管 STDOUT 已經(jīng)被重定向了。
在向 STDOUT (現(xiàn)在指向一個(gè)文件)發(fā)送一些輸出之后独悴,腳本將 STDOUT 重定向到文件描述符
3 的當(dāng)前位置(現(xiàn)在仍然是顯示器)例书。這意味著現(xiàn)在 STDOUT 又指向了它原來的位置:顯示器。
這個(gè)方法可能有點(diǎn)叫人困惑刻炒,但這是一種在腳本中臨時(shí)重定向輸出决采,然后恢復(fù)默認(rèn)輸出設(shè)置
的常用方法。

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

可以將STDIN文件描述符保存到另外一個(gè)文件描述符坟奥,然后在讀取完文件之后再將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)建讀寫文件描述符

可以用同一個(gè)文件描述符對(duì)同一個(gè)文件進(jìn)行讀寫
在對(duì)同一個(gè)文件進(jìn)行數(shù)據(jù)讀寫時(shí)树瞭,shell會(huì)維護(hù)一個(gè)內(nèi)部指針
任何讀或?qū)懚紩?huì)從指針上次的位置開始

編寫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é)束前手動(dòng)關(guān)閉文件描述符,將它重定向到特殊符號(hào)&-

在關(guān)閉文件描述符時(shí)爱谁,如果隨后在腳本中打開了同一個(gè)輸出文件晒喷,則會(huì)覆蓋已有文件

編寫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)位置時(shí)/dev/null
重定向到該位置的任何數(shù)據(jù)都會(huì)被丟掉
通常用于清除日志文件

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

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

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

命令演示:mktemp testing.XXXXXX
命令說明:mktemp命令創(chuàng)建一個(gè)臨時(shí)文件,會(huì)自動(dòng)用6個(gè)字符碼替換這6個(gè)X访敌,從而保證文件名在目錄中是唯一的凉敲。且可以創(chuàng)建多個(gè)臨時(shí)文件,每個(gè)文件都是唯一的寺旺。

編寫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)建臨時(shí)文件

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

編寫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)建臨時(shí)目錄

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

編寫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 記錄消息

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

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

編寫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 實(shí)例

案例說明:文件重定向常見于腳本需要讀入文件和輸出文件蓝撇。通過讀取.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)建臨時(shí)目錄及文件渤昌。tee命令便于將輸出同時(shí)發(fā)送給標(biāo)準(zhǔn)輸出和日志文件虽抄。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市耘沼,隨后出現(xiàn)的幾起案子极颓,更是在濱河造成了極大的恐慌,老刑警劉巖群嗤,帶你破解...
    沈念sama閱讀 218,451評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件菠隆,死亡現(xiàn)場離奇詭異,居然都是意外死亡狂秘,警方通過查閱死者的電腦和手機(jī)骇径,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,172評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來者春,“玉大人破衔,你說我怎么就攤上這事∏蹋” “怎么了晰筛?”我有些...
    開封第一講書人閱讀 164,782評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長拴袭。 經(jīng)常有香客問我读第,道長,這世上最難降的妖魔是什么拥刻? 我笑而不...
    開封第一講書人閱讀 58,709評(píng)論 1 294
  • 正文 為了忘掉前任怜瞒,我火速辦了婚禮,結(jié)果婚禮上般哼,老公的妹妹穿的比我還像新娘吴汪。我一直安慰自己,他們只是感情好蒸眠,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,733評(píng)論 6 392
  • 文/花漫 我一把揭開白布漾橙。 她就那樣靜靜地躺著,像睡著了一般楞卡。 火紅的嫁衣襯著肌膚如雪霜运。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,578評(píng)論 1 305
  • 那天臀晃,我揣著相機(jī)與錄音觉渴,去河邊找鬼介劫。 笑死徽惋,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的座韵。 我是一名探鬼主播险绘,決...
    沈念sama閱讀 40,320評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼踢京,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了宦棺?” 一聲冷哼從身側(cè)響起瓣距,我...
    開封第一講書人閱讀 39,241評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎代咸,沒想到半個(gè)月后蹈丸,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,686評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡呐芥,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,878評(píng)論 3 336
  • 正文 我和宋清朗相戀三年逻杖,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片思瘟。...
    茶點(diǎn)故事閱讀 39,992評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡荸百,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出滨攻,到底是詐尸還是另有隱情够话,我是刑警寧澤,帶...
    沈念sama閱讀 35,715評(píng)論 5 346
  • 正文 年R本政府宣布光绕,位于F島的核電站女嘲,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏奇钞。R本人自食惡果不足惜澡为,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,336評(píng)論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望景埃。 院中可真熱鬧媒至,春花似錦、人聲如沸谷徙。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,912評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽完慧。三九已至谋旦,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間屈尼,已是汗流浹背册着。 一陣腳步聲響...
    開封第一講書人閱讀 33,040評(píng)論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留脾歧,地道東北人甲捏。 一個(gè)月前我還...
    沈念sama閱讀 48,173評(píng)論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像鞭执,于是被迫代替她去往敵國和親司顿。 傳聞我的和親對(duì)象是個(gè)殘疾皇子芒粹,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,947評(píng)論 2 355

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

  • 第十五章:呈現(xiàn)數(shù)據(jù) 本章內(nèi)容 15.1 理解輸入和輸出 兩種顯示腳本輸出的方法 15.1.1 標(biāo)準(zhǔn)文件描述符 Li...
    數(shù)據(jù)萌新閱讀 295評(píng)論 0 0
  • 一、Python簡介和環(huán)境搭建以及pip的安裝 4課時(shí)實(shí)驗(yàn)課主要內(nèi)容 【Python簡介】: Python 是一個(gè)...
    _小老虎_閱讀 5,746評(píng)論 0 10
  • 官網(wǎng) 中文版本 好的網(wǎng)站 Content-type: text/htmlBASH Section: User ...
    不排版閱讀 4,383評(píng)論 0 5
  • .bat腳本基本命令語法 目錄 批處理的常見命令(未列舉的命令還比較多大溜,請(qǐng)查閱幫助信息) 1化漆、REM 和 :: 2...
    慶慶慶慶慶閱讀 8,100評(píng)論 1 19
  • 今日打卡1:共計(jì)打卡59分鐘 論證本身不會(huì)強(qiáng)迫我們?nèi)リP(guān)注什么 再合理的結(jié)構(gòu)也不能帶給具有錯(cuò)誤前提的論證新生。 如果...
    吟_f3da閱讀 201評(píng)論 0 0