"TOC" Shell學習 shell概述 shell是一個命令行解釋器,它接收應用程式/用戶命令,然後調用操作系統內核。 shell解釋器 1. Linux提供的解釋器有 2. bash和sh的關係 3. Centos預設的解析器是bash Shell腳本入門 1. 腳本格式 腳本以 !/bin/ ...
目錄
Shell學習
shell概述
shell是一個命令行解釋器,它接收應用程式/用戶命令,然後調用操作系統內核。
shell解釋器
- Linux提供的解釋器有
[shaofei@upuptop-pc ~]$ cat /etc/shells
/bin/sh
/bin/bash
/usr/bin/sh
/usr/bin/bash
- bash和sh的關係
[shaofei@upuptop-pc bin]$ ll | grep bash
-rwxr-xr-x 1 root root 964600 Aug 8 2019 bash
lrwxrwxrwx 1 root root 4 Oct 28 2019 sh -> bash
- Centos預設的解析器是bash
[shaofei@upuptop-pc bin]$ echo $SHELL
/bin/bash
Shell腳本入門
-
腳本格式
腳本以 #!/bin/bash 開頭(指定解析器) -
第一個shell腳本
[shaofei@upuptop-pc sh]$ touch helloworld.sh
[shaofei@upuptop-pc sh]$ vim helloworld.sh
#!/bin/bash
echo "helloworld"
- 腳本的常用執行方式
(1) 採用bash或sh+腳本的相對路徑或絕對路徑(不用賦予腳本+x許可權)
[shaofei@upuptop-pc sh]$ sh helloworld.sh
helloworld
[shaofei@upuptop-pc sh]$ bash helloworld.sh
helloworld
(2)採用輸入腳本的絕對路徑或相對路徑執行腳本(必須具有可執行許可權+x)
[shaofei@upuptop-pc sh]$ chmod 777 helloworld.sh
[shaofei@upuptop-pc sh]$ ./helloworld.sh
helloworld
[shaofei@upuptop-pc sh]$ /home/shaofei/sh/helloworld.sh
helloworld
註意:第一種執行方法,本質是bash解析器幫你執行腳本,所以腳本本身不需要執行許可權。第二種執行方法,本質是腳本需要自己執行,所以需要執行許可權。
- 多命令處理
[shaofei@upuptop-pc sh]$ touch batch.sh
[shaofei@upuptop-pc sh]$ vim batch.sh
#!/bin/bash
echo 'hello'
cd /home/shaofei/sh
echo 'cccc' > a.txt
Shell中的變數
系統變數
- 常用的系統變數
\(PWD,\)HOME,\(USER,\)SHELL等
- 案例
[shaofei@upuptop-pc sh]$ echo $HOME
/home/shaofei
[shaofei@upuptop-pc sh]$ echo $PWD
/home/shaofei/sh
[shaofei@upuptop-pc sh]$ echo $USER
shaofei
顯示當前Shell中所有變數:set
[shaofei@upuptop-pc sh]$ set
BASH=/bin/bash
BASHOPTS=checkwinsize:cmdhist:expand_aliases:extquote:force_fignore:histappend:hostcomplete:interactive_comments:login_shell:progcomp:promptvars:sourcepath
BASH_ALIASES=()
BASH_ARGC=()
BASH_ARGV=()
BASH_CMDS=()
BASH_LINENO=()
BASH_SOURCE=()
………………
自定義變數
-
基本語法
a. 定義變數: 變數名=變數值
b. 撤銷變數: unset 變數名
c. 聲明靜態變數: readonly 變數, 註意不能unset -
定義規則
a. 變數名可以使用字母、數字、下劃線組成,但是不能以數字開頭。環境變數建議全部大寫
b. 等號前後不能有空格
c. 在bash中,變數類型預設是字元串類型,無法直接進行數值計算
d. 變數的值如果有空格必須要用"雙引號"引起來 -
案例
創建變數A並賦值為5
[shaofei@upuptop-pc sh]$ A=5
[shaofei@upuptop-pc sh]$ echo $A
5
給變數A重新賦值為9
[shaofei@upuptop-pc sh]$ A=9
[shaofei@upuptop-pc sh]$ echo $A
9
撤銷變數A
[shaofei@upuptop-pc sh]$ unset A
[shaofei@upuptop-pc sh]$ echo $A
創建靜態的變數B
[shaofei@upuptop-pc sh]$ readonly B=2
[shaofei@upuptop-pc sh]$ echo $B
2
靜態變數不能重新賦值
[shaofei@upuptop-pc sh]$ B=10
-bash: B: readonly variable
靜態變數不能unset
[shaofei@upuptop-pc sh]$ unset B
-bash: unset: B: cannot unset: readonly variable
在bash中,變數預設類型都是字元串類型,無法直接進行數值運算
[shaofei@upuptop-pc sh]$ C=1+2
[shaofei@upuptop-pc sh]$ echo $C
1+2
變數的值如果有空格,需要使用雙引號或單引號括起來
[shaofei@upuptop-pc sh]$ D=I LOVE YOU
-bash: LOVE: command not found
[shaofei@upuptop-pc sh]$ D="I LOVE YOU"
[shaofei@upuptop-pc sh]$ echo $D
I LOVE YOU
可把變數提升為全局環境變數,可供其他Shell程式使用
[shaofei@upuptop-pc sh]$ vim helloworld.sh
在helloworld.sh文件中增加echo $B
#!/bin/bash
echo "helloworld"
echo $B
沒有列印$B的值
[shaofei@upuptop-pc sh]$ sh helloworld.sh
helloworld
修改B變數為全局環境變數
[shaofei@upuptop-pc sh]$ export B
[shaofei@upuptop-pc sh]$ sh helloworld.sh
helloworld
2
特殊變數:$n
- 基本語法
$n
功能描述:n為數字,$0 代表該腳本名稱,$1-\(9代表第一到第九個參數,十以內的參數,十以上的參數需要用大括弧包含,如\){10}
- 案例
輸出該腳本的文件名稱、輸入參數1和輸入參數2的值
[shaofei@upuptop-pc sh]$ touch param.sh
[shaofei@upuptop-pc sh]$ vim param.sh
#!/bin/bash
echo $0 $1 $2
[shaofei@upuptop-pc sh]$ sh param.sh 1 2 3
param.sh 1 2
特殊變數:$#
- 基本語法
$# (獲取所有的參數個數,常用於迴圈)
- 案例
[shaofei@upuptop-pc sh]$ vim param.sh
#!/bin/bash
echo $#
[shaofei@upuptop-pc sh]$ sh param.sh 1 2 3 4 5
5
特殊變數:$*
、$@
- 基本說法
$*
(功能描述:這個變數代表命令行中所有的參數,$*
把所有的參數看做一個整體)
$@
(功能描述: 這個變數代表命令行中所有的參數,不過$@
把每個參數區別對待)
- 案例
[shaofei@upuptop-pc sh]$ vim param.sh
#!/bin/bash
echo $@
echo $*
[shaofei@upuptop-pc sh]$ sh param.sh 1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
特殊變數:$?
- 基礎語法
$? (功能描述:最後一次執行的命令的返回狀態。如果這個變數的值為0,證明上一個命令正確執行;如果這個變數的值為非0,則證明上一個命令執行不正確了)
- 示例:
[shaofei@upuptop-pc sh]$vim param.sh
#!/bin/bash
echo $?
[shaofei@upuptop-pc sh]$ ./helloworld.sh
helloworld
[shaofei@upuptop-pc sh]$ sh param.sh
0
運算符
- 基礎語法
(1) $((運算式))
或$[運算式]
(2) expr +,-,*,/,%
加,減,乘,除,取餘
註意:expr 運算符之間要有空格
- 實例
(1)計算3+2的值
[shaofei@upuptop-pc sh]$ expr 3 + 2
5
(2)計算3-2的值
[shaofei@upuptop-pc sh]$ expr 3 - 2
1
(3)計算(2+3)* 4的值
第一種方式
[shaofei@upuptop-pc sh]$ expr `expr 2 + 3 ` \* 4
20
第二種方式
[shaofei@upuptop-pc sh]$ echo $(((3+2)*4))
20
第三種方式
[shaofei@upuptop-pc sh]$ echo $[(2+3)*4]
20
條件判斷
-
基本語法
[ condition ]
(註意:condition前後有空格) -
常用的判斷條件
(1) 兩個整數之間比較
=
字元串比較
-lt
小於(less than)
-le
小於等於(less equal)
-eq
等於(equal)
-gt
大於(greater)
-ge
大於等於(greater equal)
-ne
不等於(Not equal)
(2) 按照文件許可權進行比較
-r
有讀的許可權(read)
-w
有寫的許可權(write)
-x
有執行的許可權(execute)
(3) 按照文件類型進行判斷
-f
文件存在並且是一個常規的文件(file)
-e
文件存在(existence)
-d
文件存在且是一個目錄(directory)
案例:
- 23 是否大於等於 22
[shaofei@upuptop-pc ~]$ [ 22 -ge 23 ]
[shaofei@upuptop-pc ~]$ echo $?
1
[shaofei@upuptop-pc ~]$ [ 23 -ge 23 ]
[shaofei@upuptop-pc ~]$ echo $?
0
- HelloWorld.sh 是否有寫的許可權
-rw-rw-r-- 1 shaofei shaofei 5 May 8 23:02 a.txt
-rw-rw-r-- 1 shaofei shaofei 65 May 8 23:01 batch.sh
-rwxrwxrwx 1 shaofei shaofei 38 May 8 23:36 helloworld.sh
-rw-rw-r-- 1 shaofei shaofei 31 Dec 8 01:01 k.sh.template
-rw-rw-r-- 1 shaofei shaofei 22 May 9 21:56 param.sh
-rw-rw-r-- 1 shaofei shaofei 59 Dec 8 01:01 start.sh.template
-rwxrwxrwx 1 shaofei shaofei 21 Nov 20 09:58 test1.sh
[shaofei@upuptop-pc sh]$ [ -r helloworld.sh ]
[shaofei@upuptop-pc sh]$ echo $?
0
[shaofei@upuptop-pc sh]$ [ -x batch.sh ]
[shaofei@upuptop-pc sh]$ echo $?
1
- /home/shaofei/aaa.txt 是否存在
[shaofei@upuptop-pc sh]$ [ -e /home/shaofei/aaa.txt ]
[shaofei@upuptop-pc sh]$ echo $?
1
- 多條件判斷(&& 表示前一條命令執行成功時,才執行後一條命令,|| 表示上一條命令執行失敗後,才執行下一條命令)
[shaofei@upuptop-pc sh]$ [ -e /home/shaofei/aaa.txt ] || echo false
false
[shaofei@upuptop-pc sh]$ [ -e /home/shaofei/aaa.txt ] && echo false
[shaofei@upuptop-pc sh]$
流程語句(重點)
if判斷
- 基本語法
if [ 條件判斷式 ]; then
程式代碼
fi
或者
if [ 條件判斷式 ]
then
程式代碼
fi
註意:
[ 條件表達式 ]
中括弧和條件判斷式之間必須有空格if
後面要有空格- 第一種方式
then
前面要有分號
- 案例
輸入一個數字,如果是1 則輸出 true 如果是2 則輸出 false 如果是其他數字則不做任何操作
[shaofei@upuptop-pc sh]$ vim if.sh
#!/bin/bash
if [ $1 -eq 1 ]; then
echo true
fi
if [ $1 -eq 2 ]; then
echo false
fi
[shaofei@upuptop-pc sh]$ sh if.sh 1
true
[shaofei@upuptop-pc sh]$ sh if.sh 2
false
[shaofei@upuptop-pc sh]$ sh if.sh 123
[shaofei@upuptop-pc sh]$
case語句
- 基礎語法
case $變數名 in
"value1")
如果變數等於value1,執行程式
;;
"value2")
如果變數等於value2,執行程式
;;
……省略其他分支……
esac
註意
- case行尾必須為單詞
in
,每一個模式匹配必須以)
結束。 - 雙分號
;;
表示命令序列結束,相當於java
中的break
- 最後可以使用
*)
表示預設模式,相當於java
中的break
- 最後以
esac
結束
- 案例
輸入一個數字,如果是1 則輸出 true 如果是2 則輸出 false 如果是其他數字輸出default
[shaofei@upuptop-pc sh]$ vim case.sh
#!/bin/bash
case $1 in
1)
echo true
;;
2)
echo false
;;
*)
echo default
;;
esac
[shaofei@upuptop-pc sh]$ sh case.sh 1
true
[shaofei@upuptop-pc sh]$ sh case.sh 2
false
[shaofei@upuptop-pc sh]$ sh case.sh 3
default
[shaofei@upuptop-pc sh]$
for迴圈
- 基本語法
- 第一種方式
for (( 初始值;迴圈控制條件;變數變化 ))
do
程式
done
- 第二種方式
for 變數 in 變數1,變數2,變數
do
程式
done
- 實例
計算1-100的和
[shaofei@upuptop-pc sh]$ vim for1.sh
#!/bin/bash
sum=0
for ((i=1;i<=100;i++))
do
sum=$[$sum+$i] # or sum=$(( $sum+$i ))
done
echo $sum
[shaofei@upuptop-pc sh]$ sh for1.sh
列印所有的輸入參數 比較$* 和 $@
- 當
$*
和$@
都不被雙引號""
包括的時候,沒有區別,$*
和$@
都表示傳遞給函數或腳本的所有參數,不被雙引號""
包含時,都以$1 $2 …$n
的形式輸出所有參數。
[shaofei@upuptop-pc sh]$ vim for2.sh
#!/bin/bash
echo ---------$*
for i in $*
do
echo $i
done
echo --------$#
for j in $@
do
echo $j
done
echo --------end
[shaofei@upuptop-pc sh]$ sh for2.sh 1 2 3 4
---------1 2 3 4
1
2
3
4
--------4
1
2
3
4
--------end
- 當它們被雙引號
""
包含時,"$*"
會將所有的參數作為一個整體,以"$1 $2 …$n"
的形式輸出所有參數;"$@"
會將各個參數分開,以"$1" "$2"…"$n"
的形式輸出所有參數。
[shaofei@upuptop-pc sh]$ vim for3.sh
#!/bin/bash
echo ---------"$*"
for i in "$*"
do
echo $i
done
echo --------$#
for j in "$@"
do
echo $j
done
echo --------end
[shaofei@upuptop-pc sh]$ sh for3.sh 1 2 3 4
---------1 2 3 4
1 2 3 4
--------4
1
2
3
4
--------end
while迴圈
- 基本語法
while [ 條件表達式 ]
do
程式
done
- 案例
計算1-100的和
[shaofei@upuptop-pc sh]$ vim while.sh
#!/bin/bash
sum=0
i=0
while [ $i -le 100 ]
do
sum=$(( $sum+$i ))
i=$[$i+1]
done
echo $sum
[shaofei@upuptop-pc sh]$ sh while.sh
5050
註意: while後面有空格.
read(讀取用戶輸入)
- 基本語法
read(選項)(參數)
選項:
-p:指定讀取值時的提示符;
-t:指定讀取值時等待的時間(秒)。
參數
變數:指定讀取值的變數名
- 實例
[shaofei@upuptop-pc sh]$ vim read.sh
#!/bin/bash
read -p "input your name: " -t 3 NAME
echo "Your Name is $NAME !"
[shaofei@upuptop-pc sh]$ sh read.sh
input your name: shaofeer
Your Name is shaofeer !
函數
系統函數
- basename
- basename基本語法
basename [string/pathname][suffix]
(功能描述:basename命令會刪掉所有的首碼包括最後一個(‘/’)字元,然後將字元串顯示出來。
選項:
suffix為尾碼,如果suffix被指定了,basename會將pathname或string中的suffix去掉。
- 案例實操
[shaofei@upuptop-pc sh]$ basename /home/shaofei/123.txt
123.txt
[shaofei@upuptop-pc sh]$ basename /home/shaofei/123.txt .txt
123
- dirname
- dirname基本語法
dirname 文件絕對路徑
(功能描述:從給定的包含絕對路徑的文件名中去除文件名(非目錄的部分),然後返回剩下的路徑(目錄的部分))
- 案例實操
獲取a.txt文件的路徑
[shaofei@upuptop-pc sh]$ dirname /home/shaofei/sh/a.txt
/home/shaofei/sh
自定義函數
- 基本語法
[ function ] funname[()]
{
Action;
[return int;]
}
funname
- 經驗技巧
-(1)必須在調用函數地方之前,先聲明函數,shell腳本是逐行運行。不會像其它語言一樣先編譯。
-(2)函數返回值,只能通過$?系統變數獲得,可以顯示加:return返回,如果不加,將以最後一條命令運行結果,作為返回值。return後跟數值n(0-255)
3.案例實操
(1)計算兩個輸入參數的和
[shaofei@upuptop-pc sh]$ vim fun.sh
#!/bin/bash
function sum(){
sum=$[$1+$2]
return $sum
}
sum 1 2
echo $?
[shaofei@upuptop-pc sh]$ sh fun.sh
3
shell工具(重點)
待更新……
面試題
待更新……
個人學習總結