shell指令碼的那點小事兒--shell重定向的補充(五)
內容一:shell指令碼的重定向
1.建立檔案的讀寫描述符
複習:
1.1重定向輸入輸出
exec 重定向型別值(系統預設為0,1,2;可以自定義)<>[讀入的路徑]
2.關閉重定向描述符
2.1禁止對檔案進行讀寫,相當於對檔案上鎖,僅用於當前指令碼無法讀寫
語法結構: exec 3>&-
案例一 關閉讀寫
指令碼程式碼:
#!/bin/bash
exec 3>fileContent.sh
echo "我是傻逼" >&3
exec 3>&-
echo "我反悔了" >&3
注意:
./fileA.sh: line 15: 3: Bad file descriptor
如果關閉了,就無法寫入,如果呼叫寫入程式碼錯誤如上
案例二 關閉後再開啟
#!/bin/bash
exec 3>fileContent.sh
echo "我是傻逼" >&3
#關閉
exec 3>&-
echo "我反悔了" >&3
#重新開啟
exec 3>fileContent.sh
echo "寫入重新打開了"
3.列舉開啟的檔案描述
語法結構:lsof命令(隱藏比較深,找不到,為了安全起見)
非系統管理員使用者也可以採用這個命令外掛系統資訊
命令路徑:/usr/sbin/lsof
執行命令:檢視結果
終端輸入: /usr/sbin/lsof -a -p $$ -d 0,1,2
列印結果:
- COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
- bash 5824 Dream 0u CHR 16,0 0t1800 829 /dev/ttys000
- bash 5824 Dream 1u CHR 16,0 0t1800 829 /dev/ttys000
- bash 5824 Dream 2u CHR 16,0 0t1800 829 /dev/ttys000
分析命令
/usr/sbin/lsof->表示lsof命令
"-a"->表示將兩個選項結果進行(AND操作)拼接(格式化輸出)
"-p"->程序ID
"$$"->表示環境變數
"-d"->表示檔案描述符(例如:0、1、2)
分析結果
COMMAND->表示正在執行的命令名稱(取出名字前9個字元)->由於名字太長我們可以擷取
例如:adbfgtyyththhghg
取出:adbfgtyyt
PID->程序ID
USER->程序所屬登入名(登入使用者)
例如:管理員、成員
FD->檔案描述符號以及訪問型別(r表示讀,w表示寫,u表示讀寫)
TYPE->表示檔案型別(CHR:表示字元型,BLK表示塊型,DIR表示目錄,REG表示檔案)
DEVICE->表示裝置號
SIZE/OFF->如果存在,那麼表示檔案大小
NODE->表示本地問你節點號
NAME->表示檔名稱(檔案路徑)
案例一:錯誤程式碼
指令碼程式碼
#!/bin/bash
exec 3> fileContent.sh
exec 6> fileB.sh
exec 7< fileErr.sh
/usr/sbin/lsof -a -p $$ -d 0,1,2
#這裡錯誤的原因是 指定了3,6,7的輸入和輸出,但是/usr/sbin/lsof -a -p $$ -d 0,1,2卻只是0,1,2
#這裡不是語法錯誤而是執行結果的偏差
執行指令碼
Dream$ ./fileA.sh
總結:沒有列印當前執行命令資訊,因為你沒有指定檔案描述符
案例二:正確程式碼
指令碼程式碼
#!/bin/bash
exec 3> fileContent.sh
exec 6> fileB.sh
exec 7< fileErr.sh
/usr/sbin/lsof -a -p $$ -d 0,1,2,3,6,7
執行指令碼
./fileA.sh
- COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
- bash 5051 avalanching 0u CHR 16,0 0t1083 663 /dev/ttys000
- bash 5051 avalanching 1u CHR 16,0 0t1083 663 /dev/ttys000
- bash 5051 avalanching 2u CHR 16,0 0t1083 663 /dev/ttys000
- bash 5051 avalanching 3w REG 1,5 0 8602440700 /Users/avalanching/Desktop/fileContent.sh
- bash 5051 avalanching 6w REG 1,5 0 8602445415 /Users/avalanching/Desktop/fileB.sh
4.阻止命令的輸出
案例一:阻止命令的輸出
指令碼程式碼: 列印到系統的臨時檔案,不讓資訊在控制檯輸出
ls -al > dev/null
案例二:清空檔案
指令碼程式碼:將系統臨時檔案null中的內容寫入到需要清空的檔案中去
cat dev/null > xxxx.xx
5.建立臨檔案
5.1建立臨時檔案
案例一:保證當前目錄下檔案是唯一的
在終端直接輸入
1)動態建立檔案.XXXXXX隨機生成(一定是大寫,並且是6個X)
mktemp ava.XXXXXX
2)指定具體的檔名生成臨時檔案
mktemp ava.sh
案例二:在指令碼中建立臨時檔案
#!/bin/bash
#建立臨時檔案
#一定是6個大寫的X
tempfile=$(mktemp temp.XXXXXX)
#列印臨時檔案
echo "臨時檔案的路徑:${tempfile}"
#建立重定向修飾符
exec 3> ${tempfile}
#向臨時檔案寫入內容
echo "我是一個臨時檔案" >&3
echo "我現在接收了一些資訊,等一下程式跑完了,我就要被刪除了" >&3
echo "拜拜!" >&3
#關閉檔案
exec 3>&-
#列印臨時檔案
cat -n ${tempfile}
#刪除臨時檔案
rm -f $tempfile 2> /dev/null
內容二:指令碼匯出資料檔案
將excel表格匯出成.csv格式,利用程式碼生成.sql檔案
#!/bin/bash
outfile='test.sql'
#自定義分隔符
IFS=','
while read name gender age dev number
do
cat >> $outfile << EOF
INSERT INTO user_info_table (name, gender, age, dev, number) VALUES ('$name', '$gender', '$age','$dev', '$number');
EOF
done<${1}
#定義了IFS,read接受的輸入將會按IFS進行切割
呼叫指令碼:
./dataSource.sh test.csv
分析含義:
三個重定向
第一個重定向
done<${1}
${1}輸入一個檔案
read迴圈讀取檔案的內容,同時通過IFS分割內容,分別賦值給name, gender, age, dev, number
第二個重定向
cat >> $outfile
cat >> 讓檔案進入等待輸入,將輸入的內容重定向到$outfile中。
第三個重定向
(cat >> $outfile) << sql 語句
將sql語句輸入到等待輸入的檔案中
EOF...EOF:標誌符,標誌內容開始和結束,可以定義為其他的非關鍵字的識別符號(AAA...AAA, BBB...BBB)