Linux shell 学习笔记(16)— shell 入门总结
1. Shell 變量
Shell 變量包括自定義變量和環(huán)境變量:
- 自定義變量:腳本中自己命名定義的變量,通常為局部變量,其他
Shell程序不能訪問到; - 環(huán)境變量,操作系統(tǒng)已定義的變量,如
PATH,所有Shell程序都能訪問到,也可以通過env查看所有環(huán)境變量。
wohu@ubuntu-dev:~$ env | grep -i shell
SHELL=/bin/bash # 當(dāng)前用戶 Shell 類型
wohu@ubuntu-dev:~$ env | grep HOME
HOME=/home/wohu # 當(dāng)前用戶主目錄
wohu@ubuntu-dev:~$ env | grep LANG
LANG=en_US.UTF-8 # 操作系統(tǒng)字符集
GDM_LANG=en_US
LANGUAGE=en_US
wohu@ubuntu-dev:~$
| 變量名 | 說(shuō)明 |
|---|---|
| $PWD | 腳本執(zhí)行的當(dāng)前所在目錄 |
| $UID | 當(dāng)前操作的系統(tǒng)用戶 ID |
| $$ | 當(dāng)前操作用戶的 PID |
| $# | 當(dāng)前腳本的參數(shù)個(gè)數(shù) |
| $* | 當(dāng)前腳本的所有參數(shù) |
| $0 | 當(dāng)前執(zhí)行程序的名稱 |
| $n | 當(dāng)前程序的第 N 個(gè)參數(shù) |
| $HOME | 當(dāng)前程序的 home 目錄 |
| $USER | 查詢當(dāng)前程序使用的操作用戶 |
1.1 命名
變量名由字母、數(shù)字、下劃線組成,只能以字母或者下劃線開頭,不能使用 Shell 的保留字。不能使用空格、不能使用標(biāo)點(diǎn)符號(hào)。
1.2 賦值、調(diào)用
- 新建
hello.sh腳本,擴(kuò)展名不影響執(zhí)行:
#!/bin/bash
#自定義變量 hello
hello="Hello world!"; //注意等號(hào)兩邊不能有空格
echo $hello;
-
給
hello.sh腳本賦予執(zhí)行權(quán)限:chmod +x hello.sh。 -
調(diào)用腳本
./hello.sh,hello.sh的前面需要加上./,這是因?yàn)椴患由系脑挄?huì)去PATH下查找是否有對(duì)應(yīng)的命令可以執(zhí)行,而PATH下只有/bin、/sbin、/usr/bin、/usr/sbin,通常當(dāng)前目錄不在PATH下,就會(huì)提示comman not found,所以要用./告訴系統(tǒng)在當(dāng)前目錄下查找。
# 變量名=值
如:A=1 等號(hào)兩邊不要有空格,如果值中間存在空格,請(qǐng)使用單引或者雙引號(hào):A='張 三'# 撤銷變量
unset A# 定義靜態(tài)變量,靜態(tài)變量不可以二次賦值,靜態(tài)變量不可以 unset 撤銷
readonly B=2
1.3 刪除
使用 unset 命令可以刪除變量:
unset variable_name
例如:
#!/bin/bash
hello="Hello world!"
echo "hello="$hello
unset hello
echo "hello="$hello
輸出結(jié)果:
[oracle@195 ~]$ ./hello.sh
hello=Hello world!
hello=
1.4 作用域
普通的變量作用域?yàn)楫?dāng)前的執(zhí)行程序,程序外部不可使用當(dāng)前定義的變量。通過 export 可以把變量升級(jí)為全局環(huán)境變量,這樣當(dāng)前系統(tǒng)所有程序都可以使用這個(gè)環(huán)境變量。
export name="wohu"
測(cè)試文件,會(huì)輸出 “wohu”
#!/bin/bash
echo $name
由于定義了全局變量,所以執(zhí)行腳本可以正常輸出 $name 變量的值,反之腳本中定義的局部變量,在其它腳本中不能引用。
2. Shell 字符串
2.1 單引號(hào)、雙引號(hào)
Shell 中最常用的數(shù)據(jù)類型就是字符串和數(shù)字,除此之外也沒有數(shù)據(jù)類型了,在 Shell 中字符串可以用單引號(hào)或者雙引號(hào)來(lái)包圍,如: '/home/ubuntu'、"/home/ubuntu"、/home/ubuntu也可以沒有引號(hào)包圍。
兩者的區(qū)別在于:
- 單引號(hào)包圍的字符串會(huì)以原樣輸出,且單引號(hào)包圍的字符串中不能出現(xiàn)單引號(hào),進(jìn)行轉(zhuǎn)義也不行。
如:echo 'hello ${name}',會(huì)輸出:hello ${name};
- 雙引號(hào)包圍的字符串會(huì)將變量進(jìn)行替換,且雙引號(hào)包圍的字符串中可以出現(xiàn)雙引號(hào),進(jìn)行轉(zhuǎn)義就行。
如:
wohu@ubuntu-dev:~$ name="wohu"
wohu@ubuntu-dev:~$ echo "hello ${name}"
hello wohu
wohu@ubuntu-dev:~$
- 不被引號(hào)包圍的字符串,會(huì)對(duì)變量進(jìn)行解析,這點(diǎn)跟雙引號(hào)一樣,但是字符串中不能出現(xiàn)空格,否則空格后面的字符串會(huì)被當(dāng)作命令或者其他變量解析。
綜上,當(dāng)有變量時(shí)最好是使用雙引號(hào)包圍字符串,且變量最好有 {} 包圍,明確變量名,這也是最佳編程實(shí)踐。
2.2 獲取字符串長(zhǎng)度
獲取字符串長(zhǎng)度的方式有兩種:
${#string_name}expr length string_name
示例:
#!/bin/bash
hello="Hello world!"
echo "length of hello is:"${#hello}
expr length "$hello"
輸出結(jié)果:
length of hello is:12
12
2.3 截取字符串
使用 # 截取右邊字符,方式為 ${hello#*chars},例如:
#!/bin/bash
hello="Hello world!"
echo ${hello#*o}
輸出:
world!
表明截取了從左到右第一個(gè) o 右邊的字符串,*chars 代表忽略 chars 左邊任意長(zhǎng)度的字符串(包括 chars)。如果不寫星號(hào),那么就不會(huì)忽略 chars 左邊的字符串。
#!/bin/bash
hello="Hello world!"
echo ${hello#o}
輸出:
Hello world!
使用 % 截取左邊字符串,方式為:${hello%chars_}__。與 _#_ 不同的是,這里_在右邊,代表忽略 chars 右邊的任意長(zhǎng)度字符串,來(lái)截取 chars 左邊的字符串,其用法跟 # 類似。
看個(gè)例子:
#!/bin/bash
hello="Hello world!"
echo ${hello%o*}
輸出:
Hello w
3. Shell 數(shù)組
Shell 數(shù)組只能是一維的,不支持多維數(shù)組,并且 Shell 是弱類型的,數(shù)組中的類型不一定只有一種,且不限制數(shù)組的長(zhǎng)度大小,理論上可以是無(wú)限大小。
#!/bin/bash
#創(chuàng)建數(shù)組
array=(a b c d e)#獲取數(shù)組長(zhǎng)度
length1=${#array[@]}
echo "length1=${length1}"#另一種獲取數(shù)組長(zhǎng)度方法
length2=${#array[*]}
echo "length2=${length2}"#獲取第三個(gè)元素
echo ${array[2]}#刪除第二個(gè)元素
unset array[1]#輸出整個(gè)數(shù)組
echo ${array[@]}#for 遍歷整個(gè)數(shù)組
for i in ${array[@]}
do echo $i
done;#刪除整個(gè)數(shù)組
unset array
#查看是否已刪除
for i in ${array[@]}
do echo $i
done;
輸出:
length1=5
length2=5
c
a c d e
a
c
d
e
4. Shell 基本運(yùn)算符
4.1 算數(shù)運(yùn)算符
包括:+、-、*、/、%、=、==、!=,這些跟我們其他編程語(yǔ)言遇到的是一樣的,舉個(gè)簡(jiǎn)單例子。
#!/bin/bash
a=1;
b=2;
c=`expr $a + $b`;
echo "total is: ${c}";if [ $a == $b ]
then
echo "a 等于 b"
fiif [ $a != $b ]
then
echo "a 不等于 b"
fi
輸出:
total is: 3
4.2 關(guān)系運(yùn)算符
| 運(yùn)算符 | 說(shuō)明 |
|---|---|
| -eq | 判斷兩個(gè)數(shù)據(jù)是否相等 |
| -nq | 判斷兩個(gè)數(shù)據(jù)是否不相等 |
| -gt | 判斷左邊的數(shù)據(jù)是否大于右邊的數(shù)據(jù) |
| -lt | 判斷左邊的數(shù)據(jù)是否小于右邊的數(shù)據(jù) |
| -ge | 判斷左邊的數(shù)據(jù)是否大于等于右邊的數(shù)據(jù) |
| -le | 判斷左邊的數(shù)據(jù)是否小于等于右邊的數(shù)據(jù) |
#!/bin/bash
a=100;
b=99;
if [ $a -eq $b ]
thenecho "A"
elseecho "B"
fi
輸出:B
4.3 邏輯運(yùn)算符
| 運(yùn)算符 | 說(shuō)明 |
|---|---|
| && | 邏輯與,左右兩邊的表達(dá)式都為 true 才 true,有一個(gè)為 false 則為 false |
接下來(lái)看下程序
#!/bin/bash
a=100;
b=99;
c=90;
if [[ $a -gt $b && $a -gt $c ]]
thenecho "A"
elif [[ $b -gt $a && $b -gt $c ]]
thenecho "B"
elseecho "C"
fi
輸出:A
4.4 布爾運(yùn)算符
| 運(yùn)算符 | 說(shuō)明 |
|---|---|
| ! | 非運(yùn)算,對(duì)表達(dá)式取反,如:[ !false ] 返回 false |
| -o | 或運(yùn)算,左右兩邊的表達(dá)式存在 true 則為 true,都為 false 則為 false |
| -a | 與運(yùn)算,左右兩邊的表達(dá)式存在 false 則為 false,都為 true 則為 true |
接下來(lái)看下程序
#!/bin/basha=100;
b=99;
c=90;
if !((a == b))
thenecho "a 與 b 不相等"
elseecho "a 與 b 相等"
fiif [ $a -gt $b -a $a -gt $c ]
thenecho "A"
elif [ $b -gt $a -a $b -gt $c ]
thenecho "B"
elseecho "C"
fi
輸出:
a 與 b 不相等
A
-a 與 -o 用法相同。
4.5 字符串運(yùn)算符
| 運(yùn)算符 | 說(shuō)明 |
|---|---|
| = | 檢測(cè)兩個(gè)字符串是否相等,相等返回 true |
| != | 檢測(cè)兩個(gè)字符串是否不相等,不相等則返回 true |
| -z | 檢測(cè)字符串長(zhǎng)度是否為 0,為 0 則返回 true |
| -n | 檢測(cè)字符串長(zhǎng)度是否為 0,不為 0 則返回 true |
| $ | 檢測(cè)字符串是否為空,不為空則返回 true |
#!/bin/bash
a="zoom"
b=""
if [ -n $a ]
thenecho "a 長(zhǎng)度不為 0"
elseecho "a 長(zhǎng)度為 0"
fiif [ -z $b ]
thenecho "b 長(zhǎng)度為 0"
elseecho "b 長(zhǎng)度不為 0"
fiif [ $b ]
thenecho "b 不為空字符串"
elseecho "b 是空字符串"
fi
輸出:
a 長(zhǎng)度不為 0
b 長(zhǎng)度為 0
b 是空字符串
5. Shell 流程控制
5.1 if 條件語(yǔ)句
#!/bin/bash
if conditionA
thenexprA
elif conditionB
thenexprB
elseexprC
fi
這就是 if-elif-else,最后別忘了 fi 作為結(jié)尾。Shell 的 if 不能有空語(yǔ)句,即什么都不做的條件表達(dá)式。還有一點(diǎn)是 condition 一般用中括號(hào) [],Java都是用小括號(hào) ()。
5.2 for 循環(huán)語(yǔ)句
for 循環(huán)語(yǔ)句的基本語(yǔ)法是:
#!/bin/bash
for loop in item1 item2 ... itemN
docondition1condition2...conditionP
done
其中,for loop in 1 2 3 4 5 可被替換成 for loop in {1..5}。以及 類似于 C 中的 for 條件語(yǔ)句寫法:for((i=0;i<=5;i++))。
#!/bin/bash
for((i=0;i<=5;i++))
doecho "num is ${i}"
done
輸出:
num is 0
num is 1
num is 2
num is 3
num is 4
num is 5
5.3 while 循環(huán)語(yǔ)句
基本語(yǔ)法是:
#!/bin/bash
while conditionA
docommandA
done
看個(gè)例子:
#!/bin/bash
i=0
while(( i<=5 ))
doecho "num is ${i}"let i++
done
while 語(yǔ)句還可以用來(lái)接收用戶輸入,用法是:
while read choose
無(wú)限循環(huán)是經(jīng)常會(huì)用到的一個(gè)語(yǔ)法,下面列舉了無(wú)限循環(huán)的三種實(shí)現(xiàn)方式:
- while :
- while true
- for(( ; ; ))
5.4 case 語(yǔ)句
*) 表示默認(rèn)模式,相當(dāng)于 default,;; 表示命令序列結(jié)束,相當(dāng)于 break。
!/bin/bashcase $1 in
"1")
echo "張三"
;;"2")
echo "李四"
;;
*)
echo "王二"
;;
esac
6. Shell 函數(shù)
6.1 系統(tǒng)函數(shù)
6.1.1 basename
basename 路徑 后綴
功能描述:basename 命令會(huì)刪掉所有的前綴包括最后一個(gè) /字符,然后將字符串顯示出來(lái)。
- 不加后綴
wohu@ubuntu-dev:~/git_demo$ basename /home/wohu/git_demo/
git_demo
wohu@ubuntu-dev:~/git_demo$
- 加后綴
wohu@ubuntu-dev:~/git_demo$ basename /home/wohu/git_demo/demo.sh .sh
demo
wohu@ubuntu-dev:~/git_demo$
6.1.2 dirname
dirname 文件絕對(duì)路徑
功能描述:從給定的包含絕對(duì)路徑的文件名中去除文件名(非目錄的部分),然后返回剩下的路徑(目錄的部分)。
wohu@ubuntu-dev:~/git_demo$ dirname /home/wohu/git_demo/demo.sh
/home/wohu/git_demo
wohu@ubuntu-dev:~/git_demo$
6.2 自定義函數(shù)
#!/bin/bash
printnum()
{echo "my first function"
}echo "call funtion start"
printnum
echo "call funtion end"
輸出:
call funtion start
my first function
call funtion end
這個(gè)是不帶參數(shù)沒有返回值的例子,接下來(lái)我們來(lái)看看不帶參數(shù)沒有返回值的例子:
#!/bin/bash
plusnum()
{a=1b=3return $((a+b))
}plusnum
echo "a+b="$?
從上面我們可以看出,在調(diào)用函數(shù)后,通過 $?可以拿到返回結(jié)果。而調(diào)用方式是直接用函數(shù)名即可,不需要加上括號(hào),這點(diǎn)跟 Java 和其他面向?qū)ο蟮木幊陶Z(yǔ)言都有所不同。
下面再看一個(gè)有參數(shù)的函數(shù):
#!/bin/bash
plusnum()
{a=$1b=$2return $((a+b))
}plusnum 99 100
echo "a+b="$?
從上面我們可以看到函數(shù) plusnum 中通過 $1 和 $2 獲取傳入的參數(shù),在相加后返回結(jié)果,調(diào)用時(shí)直接跟在函數(shù)后面,并不像 Java 的函數(shù)傳參。
?
注意事項(xiàng):
- 必須在調(diào)用函數(shù)地方之前,先定義函數(shù),
Shell腳本是逐行運(yùn)行。不會(huì)像其它語(yǔ)言一樣先編譯。 - 函數(shù)返回值,只能通過
$?系統(tǒng)變量獲得,可以顯式地加return返回,如果不加,將以最后一條命令運(yùn)行結(jié)果,作為返回值。return后跟數(shù)值n(0~255)。
示例:
#!/bin/bashfunction sum()
{s=0s=$[ $1 + $2 ]echo "$s"
}# read 讀取控制臺(tái)的輸入,n1, n2 用于接收輸入內(nèi)容,
# -p:指定讀取值時(shí)的提示符;
# -t:指定讀取值時(shí)等待的時(shí)間(秒)
read -p "Please input the number1: " n1;
read -p "Please input the number2: " n2;
# 調(diào)用方法
sum $n1 $n2;
總結(jié)
以上是生活随笔為你收集整理的Linux shell 学习笔记(16)— shell 入门总结的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 2022-2028年中国农副产品行业市场
- 下一篇: 2022-2028年成都餐饮业投资分析及