Shell就是一個(gè)命令行解釋器震贵,它的作用就是遵循一定的語法將輸入的命令加以解釋并傳給系統(tǒng)童社。它為用戶提供了一個(gè)向Linux發(fā)送請(qǐng)求以便運(yùn)行程序的接口系統(tǒng)級(jí)程序戳表,用戶可以用Shell來啟動(dòng)鄙煤、掛起耻煤、停止甚至是編寫一些程序具壮。 Shell本身是一個(gè)用C語言編寫的程序,它是用戶使用Linux的橋梁哈蝇。Shell既是一種命令語言棺妓,又是一種程序設(shè)計(jì)語言(就是你所說的shell腳本)。作為命令語言炮赦,它互動(dòng)式地解釋和執(zhí)行用戶輸入的命令怜跑;作為程序設(shè)計(jì)語言,它定義了各種變量和參數(shù)吠勘,并提供了許多在高階語言中才具有的控制結(jié)構(gòu)性芬,包括循環(huán)和分支。它雖然不是 Linux系統(tǒng)內(nèi)核的一部分看幼,但它調(diào)用了系統(tǒng)內(nèi)核的大部分功能來執(zhí)行程序胖眷、創(chuàng)建文檔并以并行的方式協(xié)調(diào)各個(gè)程序的運(yùn)行橄抹。
Shell語言
使用Shell編譯靜態(tài)庫,Shell種類非常多,Bash是其中的一個(gè)使用最多的種類(免費(fèi)硼补,易用)
我使用的是mac本,自帶Shell腳本開發(fā)
Hello world!
1生巡、首先創(chuàng)建一個(gè)腳本文件:touch hello.sh
2冗栗、編寫Shell程序
#定義文件聲明 !表示約定標(biāo)記, 它會(huì)高斯系統(tǒng)這個(gè)腳本需要什么樣的解釋器來執(zhí)行宵凌,即一種腳本體現(xiàn)
#!/bin/bash
echo "Hello world!"
3鞋囊、修改文件權(quán)限
首先查看文件權(quán)限:ls -l hello.sh
修改權(quán)限:chmod +x ./hello.sh
4、執(zhí)行腳本文件
命令:./hello.sh
語法
1瞎惫、注釋
# 表示注釋
在Shell腳本中沒有多行注釋溜腐,只有單行注釋
2译株、變量
變量定義注意事項(xiàng):
- 定義變量時(shí)候,變量名不需要加$符號(hào)
- 變量名和等號(hào)不能夠有空格
- 變量名首字母必須是是字母或者下劃線(a_z,A_Z)
- 變量名中間不允許有空格
2.1只讀變量:關(guān)鍵字readonly
name="小生生"
readonly name
_age=18
name="小白"
echo $name
echo $_age
這段代碼會(huì)有警告:#readonly variable
2.2刪除變量
語法:unset 變量名
只讀變量 無法刪除
2.3變量類型
- 本地變量挺益,作用域:整個(gè)bash進(jìn)程可以使用 語法: name="xiaoming"
- 局部變量歉糜,作用域:當(dāng)前代碼段(修飾符local) 語法:local name="xiaohong"
- 環(huán)境變量,作用域:當(dāng)前shell進(jìn)程以及子進(jìn)程 語法:export name="xiaohei"
- 位置變量望众,給我們腳本文件傳遞參數(shù) 使用${數(shù)字} 0表示文件名稱匪补,從1開始 執(zhí)行的時(shí)候可以傳參,/hello.sh xiaohong 150 男
#給我們的腳本文件傳遞參數(shù)
name=${1}
age=${2}
sex=${3}
echo "姓名:${name}, 年齡 ${age}, 性別 ${sex}"
- 特殊變量:
1)${0}文件名稱
2)${?}表示返回上一個(gè)命令執(zhí)行狀態(tài)返回值:0表示成功烂翰,1表示執(zhí)行結(jié)果夯缺,2表示程序狀態(tài)返回碼(0-255)系統(tǒng)預(yù)留錯(cuò)誤(1,2甘耿,127)- $# 表示參數(shù)的個(gè)數(shù)
4)$* 或者 $@ 表示參數(shù)列表(區(qū)別:前者將所有參數(shù)組成一個(gè)字符串踊兜,后者分開的字符串)
5)$$ 獲取當(dāng)前shell進(jìn)程ID
6) $! 表示執(zhí)行上一個(gè)指令的PID(進(jìn)程ID)
- $# 表示參數(shù)的個(gè)數(shù)
3、字符串
3.1 單引號(hào)
name='Andy'
3.2 雙引號(hào)
name="Andy"
3.3 字符串拼接
方式一
name='Andy'
age=18
sex=2
info=${name}${age}${sex}
echo $info
方式二
name='Andy'
age=18
sex=2
info="${name},${age},${sex}"
echo $info
3.4 獲取字符串長度
語法結(jié)構(gòu):${#變量名}
name="Andy"
echo ${#name}
3.5 字符串截取
語法:${變量名:開始位置:截取位置}
name="I am Andy"
length=${#name}
result=${name:5:length-1}
echo $result
3.6字符串刪除
語法一:${變量名#刪除字符串 正則表達(dá)式}
作用:從字符串開頭開始匹配要?jiǎng)h除的字符串
#刪除頭字符 只能刪除從頭開始的
name="I am Andy"
result=${name#I}
echo $result 結(jié)果am Andy
#查找制定字符棵里,并刪除前面所有字符(包含自己)
name="I am Andy"
result=${name#*A}
echo $result 結(jié)果ndy
#刪除制定范圍(只能從第一個(gè)開始刪除润文,刪除到那里)
name="I am Andy"
result=${name#I*A}
echo $result 結(jié)果ndy
語法二:${變量名##刪除字符串 正則表達(dá)式}
作用:從字符串的結(jié)尾開始匹配 刪除字符串
name="I am Andy"
result=${name##*A}
echo $result 結(jié)果ndy
語法三:${變量名%刪除字符串 正則表達(dá)式}
作用:從字符串結(jié)尾開始匹配,刪除匹配的字符串
name="I am Andy"
result=${name%Andy}
echo $result
#查找自定字符第一個(gè)殿怜,并刪除前面所有字符(包含自己)
name="I am Andy"
result=${name%A*}
echo $result 結(jié)果 I am
4典蝌、布爾運(yùn)算符
“!”:非運(yùn)算,
a=100
b=200
if [ $a != $b ]
then
echo "a不等于b"
fi
“-o”:或運(yùn)算
a=100
b=200
if [ $a -lt 200 -o $b -gt 200 ]
then
echo "成立"
fi
“-a”: 與運(yùn)算
a=100
b=200
if [ $a -lt 200 -a $b -gt 200]
then
echo "成立"
else
echo "不成立"
fi
5头谜、邏輯運(yùn)算符
"&&":邏輯且
a=100
b=00
if [ $a -lt 200 ] && [ $b -gt 200 ]
then
echo "成立"
else
echo "不成立"
fi
“||”:邏輯或
a=100
b=200
if [ $a -lt 200 ] || [$b -gt 200 ]
then
echo "成立"
else
echo "不成立"
fi
6骏掀、字符串運(yùn)算
6、1
“=”:檢測兩個(gè)字符串是否相等柱告,如果相同則返回true
a="Andy"
b="你好"
if [ $a = $b ]
then
echo "字符串相等"
else
echo "字符串不相等"
fi
6截驮、2
“!=”:檢測兩個(gè)字符串是否相等,如果不相等返回true
a="Andy"
b="你好"
if [ $a != $b ]
then
echo "字符串a(chǎn)不等于字符串b"
else
echo "字符串a(chǎn)等于字符串b"
fi
“-z”:檢測字符串的長度是否為0际度,如果是返回true
a="Andy"
if [ -z $a ]
then
echo "a不存在"
else
echo "a存在"
fi
“-n”:檢測字符串長度是否為0葵袭,如果不是0,返回true
a="Andy"
if [ -n "$a" ]
then
echo "a存在"
else
echo "a不存在"
fi
7乖菱、文件測試運(yùn)算符
file="/Users/zhaoruisheng/Desktop"
"-d file":檢測一個(gè)文件是不是一個(gè)目錄坡锡,如果是返回true
file="/Users/zhaoruisheng/Desktop"
if [ -d $file ]
then
echo "是一個(gè)目錄"
else
echo "不是一個(gè)目錄"
fi
"-r file":檢測文件是否可讀,如果是返回true
file="/Users/zhaoruisheng/Desktop/Shell/hello.sh"
if [ -r $file ]
then
echo "可讀"
else
echo "不可讀"
fi
"-w file:檢測文件是否可寫窒所,如果是返回true
file="/Users/zhaoruisheng/Desktop/Shell/hello.sh"
if [ -w $file ]
then
echo "可寫"
else
echo "不可寫"
fi
"-x file":檢測文件是否是可執(zhí)行文件鹉勒,如果是,那么返回true
file="/Users/zhaoruisheng/Desktop/Shell/hello.sh"
if [ -w $file ]
then
echo "可執(zhí)行"
else
echo "不可執(zhí)行"
fi
"-f file"檢測一個(gè)文件是否是普通文件(既不是目錄吵取,也不是設(shè)備文件)禽额,如果是返回true
file="/Users/zhaoruisheng/Desktop/Shell/hello.sh"
if [ -f $file ]
then
echo "普通文件"
else
echo "系統(tǒng)文件"
fi
"-s file":檢測文件是否為空(文件有內(nèi)容),如果是皮官,那么返回true
file="/Users/zhaoruisheng/Desktop/Shell/hello.sh"
if [ -s $file ]
then
echo "文件有內(nèi)容"
else
echo "文件沒有內(nèi)容"
fi
"-e file":檢測文件是否存在(包含了:目錄和文件)脯倒,如果是实辑,返回true
file="/Users/zhaoruisheng/Desktop/Shell/hello.sh"
if [ -e $file ]
then
echo "文件存在"
else
echo "文件不存在"
fi
控制流程
1、if語句
語法結(jié)構(gòu):
if [條件]
then
代碼
fi
if else 語句
if [條件]
then
代碼
else
代碼
fi
if-else-if-else
語法結(jié)構(gòu)
if [條件]
then
代碼
elif [條件]
then
代碼
else
代碼
fi
2藻丢、switch
語法結(jié)構(gòu)
case 值 in
模式1)
代碼
;;
模式2)
代碼
;;
模式3)
代碼
;;
esac
number=1
case $number in
1) echo "等于1";;
2) echo "等于2";;
3) echo "等于3";;
esac
3徙菠、for循環(huán)
語法結(jié)構(gòu)
for 變量名 in item1 item2 ...
do
代碼
done
for name in "Andy" "小黑" "小吧"
do
echo $name
done
#讀取文件通配符
file="/Users/zhaoruisheng/Desktop/Shell/*"
for name in ${file}
do
echo $name
done
#嵌套循環(huán)
for ((a = 1; a < 5; a++ ))
do
echo $a
for ((b = 1; b < 5; b++ ))
do
echo $b
done
done
4、while循環(huán)
語法結(jié)構(gòu)
while(條件)
do
代碼
done
a=1
while(($a<10))
do echo $a
a=`expr $a + 1`
done
5郁岩、until循環(huán)
語法結(jié)構(gòu)
until ((條件))
do
代碼
done
i=1
until (( $i > 1 ))
do
echo "i小于1"
done
6、break
1缺狠、跳出單個(gè)循環(huán)
for ((i=0; i < 10; i ++))
do
echo "當(dāng)前i的值是$i"
if [ $i == 5 ]
then
break
fi
done
2问慎、跳出內(nèi)部循環(huán)
for ((i = 0; i< 10; i++))
do
echo "外層循環(huán)i的值$i"
for ((j =0; j<10;j++))
do
echo "內(nèi)層循環(huán)j的值$j"
if [ $j == 5 ]
then
echo "退出內(nèi)層循環(huán)"
break
fi
done
done
3、跳出外部循環(huán)(break 數(shù)字:表示退出幾層循環(huán))
for ((i = 0; i< 10; i++))
do
echo "外層循環(huán)i的值$i"
for ((j =0; j<10;j++))
do
echo "內(nèi)層循環(huán)j的值$j"
if [ $j == 5 ]
then
echo "退出內(nèi)層循環(huán)"
break 2
fi
done
done
7挤茄、continue
for ((i=0;i < 5; i++))
do
echo "外層循環(huán)i的值$i"
if [ $i == 2]
then
echo "跳出"
continue
fi
done
文件包含
語法一: ./filename
文件A -> fileA.sh
腳本內(nèi)容
#!/bin/bash
echo "我是文件A"
文件B -> fileB.sh
腳本內(nèi)容
#!/bin/bash
#文件B包含文件A
source ./fileA.sh
echo "我是文件B"
cat命令
作用
- 查看文件內(nèi)容如叼,
- 連接文件,
- 創(chuàng)建一個(gè)或者多個(gè)文件穷劈,
- 重定向輸出到終端
- 重定向到文件
語法:
- 查看文件內(nèi)容 cat test.sh
- 查看內(nèi)容帶行號(hào) cat -n test.sh
- 查看內(nèi)容(有內(nèi)容的行) cat -b test.sh
- 在每一行的后面增加一個(gè)美元符($) cat -e test.sh 作用于多行內(nèi)容轉(zhuǎn)換為一行內(nèi)容
- 單獨(dú)輸入一個(gè)cat時(shí)候笼恰,接收輸入內(nèi)容,并輸出內(nèi)容 退出control+c
獲取用戶輸入
read命令
1歇终、接收一個(gè)輸入內(nèi)容
#寫法一:
echo "請(qǐng)輸入你的名字"
read name
echo "你的名字是${name}"
#寫法二:
read -p "請(qǐng)輸入你的名字" name
echo "你的名字是${name}"
2社证、超時(shí)->輸入的時(shí)候,過了多少時(shí)間沒有輸入评凝,就過期
if read -t 6 -p "請(qǐng)輸入你的名字" name
then
echo "你的名字是${name}"
else
echo "超時(shí)"
fi
3追葡、隱藏輸入內(nèi)容,相當(dāng)于輸入密碼 -s
read -s -p "請(qǐng)輸入你的密碼" name
echo "你的密碼是${name}"
4奕短、從文件中讀取內(nèi)容
cat testA.sh | while read line
do
echo "內(nèi)容${line}"
done
printf命令使用
1宜肉、prindf命令和echo命令的區(qū)別
- printf不換行,echo自動(dòng)換行
- print用于格式打印翎碑,echo用于標(biāo)準(zhǔn)輸出
2谬返、printf語法結(jié)構(gòu)
printf format-string 參數(shù)列表
#打印輸出表頭
printf "%-10s %-8s %-4s \n" 姓名 性別 體重kg
#打印輸出內(nèi)容
printf "%-10s %-8s %-4s \n" Andy 男 64kg
printf "%-10s %-8s %-4s \n" jar 男 65kg
printf "%-10s %-8s %-4s \n" 帥牛哥 男 100kg
"%-10"指的是一個(gè)寬度為10的字符,"-"表示左對(duì)齊
"s"表示字符串字符
"%-4.sf"指的是一個(gè)寬度為4日杈,小數(shù)點(diǎn)2位遣铝,"f"表示小數(shù)
3、printf也可以用單引號(hào)或者不用
多個(gè)參數(shù)輸出需要用符號(hào)
函數(shù)
1达椰、語法結(jié)構(gòu)
function testFunction() {
echo 第一個(gè)參數(shù)
}
testFunction
輸入/輸出重定向
1翰蠢、輸入輸出重定向->控制臺(tái)/文件
1.1、將file中的內(nèi)容讀取到控制臺(tái) wc 文件名稱
- 第一個(gè)參數(shù):文本行數(shù)
- 第二個(gè)參數(shù):文本詞數(shù)
- 第三個(gè)參數(shù):文本字節(jié)數(shù)
使用cat 來使用輸入重定向
1.2啰劲、輸出重定向 “>”:我們把方向指向一份文件梁沧,那么將文件中的內(nèi)容刪除,寫入新的內(nèi)容
">>"追加
腳本文件fileA.sh代碼
#!/bin/bash
echo "我是文件A"
腳本文件fileB.sh代碼
#!/bin/bash
echo "我是文件B"
echo "Hello Dream" > fileA.sh
echo "追加" >> fileA.sh
執(zhí)行腳本代碼
./fileB.sh
總結(jié):替換內(nèi)容->將fileB.sh輸出內(nèi)容替換了fileA.sh中內(nèi)容
2蝇裤、“expr”命令
- 方式一
a=100
b=200
val=`expr $a + $b`
echo "val的值${val}"
- 方式二
a=100
b=200
val=$(expr $a + $b)
echo "val的值是${val}"
- 方式3
a=100
b=200
val=$[ $a + $b ]
echo "val的值是${val}"
3廷支、浮點(diǎn)數(shù)
3.1频鉴、bash的基本用法
"bc"命令:是在我們的shell腳本語言中中提示符,通過bc命令訪問bash計(jì)算器
- 第一步:輸入bc命令打開計(jì)算器
- 第二步:開始計(jì)算
- 第三步:直接輸入
- quit 退出
將bash計(jì)算器應(yīng)用到shell腳本中
語法結(jié)構(gòu):val=$(echo "options;expression" | bc)
options:表示選項(xiàng),可以設(shè)置精度
expression:表達(dá)式
#案例一:基本語法
val=$(echo "sacal=1;1.56 * 100" | bc)
echo "val的值為:$val"
總結(jié):1.56*100->稱為表達(dá)式
sacal=1表示選項(xiàng)
#案例二:
val1=1.314
val2=0.618
val3=$(echo "$val1 * $val2" | bc)
val4=$(echo "$val3 * $val2" | bc)
echo "val4的值是:$val4"
#總結(jié):簡單計(jì)算可以恋拍,復(fù)雜計(jì)算麻煩
#案例三:bc命令+輸入重定向
語法格式:
val=$(bc<<FG
iptions
statements
expression
FG
)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
val1=1.314
val2=0.618
val3=$(bc << FG
a = ($val1 * $val2)
b = ($a * $val2)
a + b
FG
)
echo "val3的值是:$val3"
管道
使用場景:有時(shí)候我們需要一個(gè)命令的輸出作為另一個(gè)命令的輸入
語法結(jié)構(gòu): command1 | command2
4垛孔、重定向->外部文件操作
4.1、理解輸入和輸出施敢、錯(cuò)誤概念:shell腳本語言中將輸入周荐、輸出、錯(cuò)誤分為 了三種描述符(3中狀態(tài))僵娃,分別對(duì)應(yīng)的值(0概作,1,2)
- 第一種:STDIN->標(biāo)準(zhǔn)輸入->0->鍵盤輸入
第一點(diǎn):直接輸入cat命令->接收鍵盤輸入默怨,然后打印到控制臺(tái)
第二點(diǎn):采用cat接收一個(gè)非STDIN文件輸入讯榕,說白了就是讀取文件內(nèi)容,輸出到控制臺(tái) cat fileA.sh - 第二種:STDOUT->標(biāo)準(zhǔn)輸出->1->對(duì)應(yīng)終端顯示
第一點(diǎn):重定向->輸出文件中匙睹,原來輸出到控制到愚屁,現(xiàn)在重定向到文件
#ls-l:顯示文件時(shí)間信息()
#who:打印當(dāng)前登錄系統(tǒng)的用戶信息
who >> testB.sh
cat testB.sh
#ni hao
我從不裝逼
zhaoruisheng console Mar 6 13:20
zhaoruisheng ttys000 Mar 6 13:20
第二點(diǎn):重定向錯(cuò)誤->輸入到文件中
ls -al a.sh > testB.sh
總結(jié)一:到我們的命令發(fā)生錯(cuò)誤時(shí)候,shell腳本語言并不會(huì)將錯(cuò)誤信息重定向到輸出重定向文件痕檬,shell及時(shí)創(chuàng)建了輸出重定向文件霎槐,當(dāng)時(shí)也不會(huì)寫入內(nèi)容
總結(jié)二:雖然創(chuàng)建了文件,但是文件內(nèi)容是空的
總結(jié)三:shell腳本語言對(duì)于錯(cuò)誤信息處理和普通信息輸出是分開的梦谜,那么如果我們希望報(bào)錯(cuò)錯(cuò)誤信息栽燕,那么需要采用STDERR實(shí)現(xiàn)
- 第三種:STUERR->標(biāo)準(zhǔn)錯(cuò)誤-> 2
ls -al a.sh 2> testB.sh
5、重定向錯(cuò)誤信息
5.1改淑、只定向錯(cuò)誤
- 將STDERR文件描述改為2 ls -al a.sh 2> testB.sh
- 將STDOUT和STDERROR結(jié)合使用
第一步:執(zhí)行命令
ls -al testA.sh fileA.sh 2> testB.sh
第二步:查看結(jié)果
-rwxr-xr-x@ 1 zhaoruisheng staff 74 3 5 16:53 testA.sh
5.2碍岔、重定向錯(cuò)誤和重定向數(shù)據(jù) - STDOUT和STDERROR結(jié)合使用(1和2),保存錯(cuò)誤信息和數(shù)據(jù)朵夏,即:在后面追加就行了蔼啦,可以追加到別的文件
第一步:執(zhí)行命令ls -al testA.sh fileA.sh 2> testB.sh 1>> testB.sh
第二步:查看數(shù)據(jù)和錯(cuò)誤
ls: fileA.sh: No such file or directory
-rwxr-xr-x@ 1 zhaoruisheng staff 74 3 5 16:53 testA.sh - 同時(shí)將數(shù)據(jù)和錯(cuò)誤信息輸入到同一個(gè)文件 “&>”
ls -al testA.sh fileA.sh 2> testB.sh 1&> testB.sh
輸入和輸出
6、重定向輸出->深入一點(diǎn)
6.1仰猖、臨時(shí)重定向 “&”
案例一:
echo "Hello world" >&2
echo "你好"
案例二:
當(dāng)執(zhí)行 ./hello.sh 2> testB.sh后 Hello world 被重定向到testB中了捏肢,使用>&2后就會(huì)別被標(biāo)記為錯(cuò)誤信息, 1位輸出信息
6.2饥侵、永久重定向 exec命令
案例一:保存數(shù)據(jù)
exec 1> testB.sh
echo "Hello world"
echo "你好"
echo "掛卡很快就"
echo "kjhlakjhflha"
案例二:保存錯(cuò)誤信息和數(shù)據(jù)
exec 1> fileContent.sh
echo "Hello world"
echo "你好"
echo "JAR童鞋"
exec 2> error.sh
echo "我報(bào)錯(cuò)了" >&2
echo "不好意思鸵赫,我拒絕你,你不配"
7躏升、重定向輸入
從文件A中讀取內(nèi)容到文件B中
exec 0< fileContent.sh
count=1
while read line
do
echo "當(dāng)前行數(shù):$count 讀取內(nèi)容:$line"
count=$[ $count + 1 ]
done
8辩棒、重建自己的重定向
0、1、2是系統(tǒng)提供的一睁,我們可以自定義
- 創(chuàng)建自己的輸出文件描述(創(chuàng)建新的文件或者替換內(nèi)容)
案例一:創(chuàng)建新的文件或者替換內(nèi)容
exec 3> fileContent.sh
echo "Hello world"
echo "你好" >&3
echo "JAR童鞋"
exec 2> error.sh
echo "我報(bào)錯(cuò)了" >&2
echo "不好意思钻弄,我拒絕你,你不配"
案例二:追加內(nèi)容
exec 3>> fileContent.sh
echo "Hello world"
echo "你好" >&3
echo "JAR童鞋" >&3
exec 2> error.sh
echo "我報(bào)錯(cuò)了" >&2
echo "不好意思者吁,我拒絕你窘俺,你不配"
- 恢復(fù)文件原始的描述符
#最開始是3重定向到1
exec 3>&1
exec > fileContent.sh
echo "Hello world"
exec 2> error.sh
echo "我報(bào)錯(cuò)了" >&2
echo "不好意思,我拒絕你复凳,你不配"
exec 1>&3
echo "搞完了"
- 創(chuàng)建文件輸入的描述符
exec 6<&0
exec 0< fileContent.sh
count=1
while read line
do
echo "當(dāng)前行數(shù):$count 讀取內(nèi)容:$line"
count=$[ $count + 1 ]
done
#恢復(fù)之前文件描述符
exec 0<&6
echo "輸出"
read -p "你是不是一個(gè)男人瘤泪?" isMan
case $isMan in
Y|y) echo "男人" ;;
N|n) echo "女人" ;;
*) echo "人妖" ;;
- 創(chuàng)建讀寫的描述符
exec 3<>fileContent.sh
#從fileContent中讀取文件
read line <&3
echo "Read: $line"
#寫入文件
echo "I have a deam" >&3
注意:替換了第二行?因?yàn)槲覀兾募羔樧x取完了第一行育八,文件指針指向了第二行均芽,所以第二行之后所有的內(nèi)容被替換
- 關(guān)閉文件描述符:關(guān)閉后,在當(dāng)前腳本中讀寫都不允許单鹿,讀取和寫入都會(huì)報(bào)錯(cuò)
語法結(jié)構(gòu):exec 3>&-
exec 3>fileContent.sh
echo "我是天才">&3
exec 3>&-
echo "寫入鎖定">&3
read line <&3
echo "數(shù)據(jù)讀取:$line"
- 打開文件描述
lsof命令:非管理員用戶也可以采用這個(gè)命令插件系統(tǒng)信息
命令路徑:/uset/sbin/lsof
/usr/sbin/lsof -a -p $$ -d 0,1,2
~~~~~輸出
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
bash 519 zhaoruisheng 0u CHR 16,0 0t4515 665 /dev/ttys000
bash 519 zhaoruisheng 1u CHR 16,0 0t4515 665 /dev/ttys000
bash 519 zhaoruisheng 2u CHR 16,0 0t4515 665 /dev/ttys0000
分析:/usr/sbin/lsof->表示lsof命令
"-a"->表示將兩個(gè)選項(xiàng)結(jié)果進(jìn)行(AND操作)拼接(格式化輸出)
"-p"->進(jìn)程ID
"$$"->表示環(huán)境變量
"-d"->表示文件描述符(例如:0深纲、1仲锄、2)
分析結(jié)果
COMMAND->表示正在運(yùn)行的命令名稱(取出名字前9個(gè)字符)
PID->進(jìn)程ID
USER->進(jìn)程所屬登錄名
FD->文件描述符號(hào)以及訪問類型(r讀、w寫湃鹊、u讀寫)
TYPE->表示文件類型(CHR:字符型儒喊,BLK塊類型,DIR目錄币呵、REG文件)
DEVICE->設(shè)備號(hào)
SIZE/OFF->如果存在怀愧,那么表示文件大小
NODE->表示本地文件節(jié)點(diǎn)號(hào)
NAME->表示文件名稱(路徑)
exec 3> fileContent.sh
exec 6> fileB.sh
exec 7< fileErr.sh
/usr/sbin/lsof -a -p $$ -d 0,1,2,3,6,7
~~~~~~執(zhí)行結(jié)果
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
bash 2268 zhaoruisheng 0u CHR 16,0 0t5834 665 /dev/ttys000
bash 2268 zhaoruisheng 1u CHR 16,0 0t5834 665 /dev/ttys000
bash 2268 zhaoruisheng 2u CHR 16,0 0t5834 665 /dev/ttys000
bash 2268 zhaoruisheng 3w REG 1,8 0 55364172 /Users/zhaoruisheng/Desktop/Shell/fileContent.sh
bash 2268 zhaoruisheng 6w REG 1,8 0 55378786 /Users/zhaoruisheng/Desktop/Shell/fileB.sh
- 阻止命令輸出 > /dev/null
案例一:
打印命令+ > /dev/null
案例二:清空文件
cat /dev/null > fileContent.sh
- 創(chuàng)建臨時(shí)文件
創(chuàng)建本地的臨時(shí)文件
案例一:保證當(dāng)前文件目錄唯一
mktemp nihao.sh
#在腳本中創(chuàng)建臨時(shí)文件
#創(chuàng)建臨時(shí)文件
tempfile=$(mktemp tempfile.xxxxxxx)
#重定向文件
exec 3> $tempfile
#打印文件名稱
echo "文件名稱 $tempfile"
#給文件輸入內(nèi)容
echo "我是個(gè)臨時(shí)文件" >&3
echo "我是個(gè)臨時(shí)文件1" >&3
echo "我是個(gè)臨時(shí)文件2" >&3
#關(guān)閉文件
exec 3>&-
#打印文件內(nèi)容
cat $tempfile
#刪除臨時(shí)文件
rm -f $tempfile 2> /dev/null
在/temp目錄下創(chuàng)建臨時(shí)文件 "-t"
案例一:
mktemp -t testfile.xxxxx
~~~~~執(zhí)行結(jié)果
/var/folders/5c/f1wlx5wn2nv1zl04kg_35prm0000gn/T/testfile.xxxxx.8wF10COI(臨時(shí)目錄)
注意:不同系統(tǒng)臨時(shí)目錄不一樣
案列二:
#創(chuàng)建臨時(shí)目錄
tempfile=$(mktemp -t tempfile.xxxx)
echo "我是一個(gè)臨時(shí)目錄" > $tempfile
#追加內(nèi)容
echo "追加內(nèi)容" >> $tempfile
#打印文件路徑
echo "文件路徑:$tempfile"
cat $tempfile
#刪除文件
rm -f $tempfile 2> /dev/null
創(chuàng)建臨時(shí)目錄 "-d"
#當(dāng)前目錄下創(chuàng)建臨時(shí)目錄
tempfile=$(mktemp -d testfile.xxxx)
#進(jìn)入臨時(shí)文件
cd $tempfile
#在臨時(shí)目錄中創(chuàng)建臨時(shí)文件
tempfile1=$(mktemp testfile.xxxx)
tempfile2=$(mktemp testfile.xxxxx)
#自定義文件描述->重定向輸出
exec 7>$tempfile1
exec 8>$tempfile2
#打印臨時(shí)目錄路徑
echo "臨時(shí)目錄路徑:$tempfile"
#向臨時(shí)文件寫入內(nèi)容
echo "我是臨時(shí)文件1" >&7
echo "我是臨時(shí)文件2" >&8
cat $tempfile1
cat $tempfile2
- 記錄消息
作用:將輸出同事發(fā)送顯示器和日志文件,重定向的話需要兩次余赢,采用tee命令一次完成
#采用管道芯义,一個(gè)命令的輸出作為另一個(gè)命令的輸入
案例一:重定向->輸出->覆蓋
date | tee testB.sh
案例二:追加
date | tee -a testB.sh
案例三:應(yīng)用到腳本中
操作數(shù)據(jù)庫
導(dǎo)出SQL文件
場景:有一個(gè)excel文件,導(dǎo)出.csv文件轉(zhuǎn)成.sql文件
腳本實(shí)現(xiàn)
#!/bin/bash
#定義數(shù)據(jù)庫文件(.sql)文件
outfile='test.sql'
#定義域分隔符->分割字符串
IFS=','
while read name sex age mv yd phone
do
cat >> $outfile << EOF
INSERT INTO t_test (name, sex, age, mv, yd, phone) VALUES ('$name', '$sex', '$age', '$mv', '$yd', '$phone');
EOF
done < ${1}
執(zhí)行操作./hello.sh csvtest.csv
分析:
三個(gè)重定向操作
- 第一個(gè):輸入重定向done < ${1}妻柒,{1}第一個(gè)參數(shù)恰好是一個(gè)文件扛拨,read通過循環(huán)一行行讀取,{2}是第二個(gè)參數(shù)举塔,同事read還會(huì)通過IFS進(jìn)行字符串分割绑警,分割之后自動(dòng)給參數(shù)賦值
- 第二個(gè):輸出重定向
cat >> test.sql:等到輸入內(nèi)容,敲回車后輸出到制定重定向文件 - 第三個(gè):輸入重定向'<<'追加
數(shù)據(jù)庫操作
- 鏈接數(shù)據(jù)庫->登錄數(shù)據(jù)庫