1. 程式人生 > >shell指令碼的那點小事兒--shell重定向的補充(五)

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

列印結果:

  1.         COMMAND  PID  USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
  2.         bash    5824 Dream    0u   CHR   16,0   0t1800  829 /dev/ttys000
  3.         bash    5824 Dream    1u   CHR   16,0   0t1800  829 /dev/ttys000
  4.         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

  1. COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
  2. bash 5051 avalanching 0u CHR 16,0 0t1083 663 /dev/ttys000
  3. bash 5051 avalanching 1u CHR 16,0 0t1083 663 /dev/ttys000
  4. bash 5051 avalanching 2u CHR 16,0 0t1083 663 /dev/ttys000
  5. bash 5051 avalanching 3w REG 1,5 0 8602440700 /Users/avalanching/Desktop/fileContent.sh
  6. 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)

注意:以上的縮排是為了方便檢視層級關係,如果在執行程式碼中報錯(not found command),請去除縮排,注意if後的空格