Shell基礎(chǔ)回顧

個(gè)人專題目錄

?

1. Shell解析器

  1. Linux提供的Shell解析器有:
$ cat /etc/shells 
/bin/sh
/bin/bash
/sbin/nologin
/bin/dash
/bin/tcsh
/bin/csh
  1. bash和sh的關(guān)系
$ ll /bin | grep bash
-rwxr-xr-x. 1 root root 941880 5月  11 2016 bash
lrwxrwxrwx. 1 root root      4 5月  27 2017 sh -> bash
  1. Centos默認(rèn)的解析器是bash
$ echo $SHELL
/bin/bash

2. Shell腳本入門

  1. 腳本格式

腳本以#!/bin/bash開(kāi)頭(指定解析器)這一行決定了腳本可以像一個(gè)獨(dú)立的可執(zhí)行文件一樣執(zhí)行,而不用在終端之前輸入sh,bash,python,php等。

  1. 第一個(gè)Shell腳本:helloworld
    1. 需求:創(chuàng)建一個(gè)Shell腳本,輸出helloworld
    2. 案例實(shí)操:
$ touch helloworld.sh
$ vi helloworld.sh

在helloworld.sh中輸入如下內(nèi)容
#!/bin/bash
echo "helloworld"
  1. 腳本的常用執(zhí)行方式

第一種:采用bash或sh+腳本的相對(duì)路徑或絕對(duì)路徑(不用賦予腳本+x權(quán)限)

# sh+腳本的相對(duì)路徑
$ sh helloworld.sh

#sh+腳本的絕對(duì)路徑
$ sh /home/xubh/datas/helloworld.sh 
helloworld

#bash+腳本的相對(duì)路徑
$ bash helloworld.sh 
Helloworld

#bash+腳本的絕對(duì)路徑
$ bash /home/xubh/datas/helloworld.sh 
Helloworld

第二種:采用輸入腳本的絕對(duì)路徑或相對(duì)路徑執(zhí)行腳本(必須具有可執(zhí)行權(quán)限+x)

# 首先要賦予helloworld.sh 腳本的+x權(quán)限
$ chmod 777 helloworld.sh

# 執(zhí)行腳本
# 相對(duì)路徑
$ ./helloworld.sh 
Helloworld
# 絕對(duì)路徑
$ /home/xubh/datas/helloworld.sh 
Helloworld

注意:第一種執(zhí)行方法,本質(zhì)是bash解析器幫你執(zhí)行腳本,所以腳本本身不需要執(zhí)行權(quán)限。第二種執(zhí)行方法,本質(zhì)是腳本需要自己執(zhí)行,所以需要執(zhí)行權(quán)限。

  1. 第二個(gè)Shell腳本:多命令處理
# 在/home/xubh/目錄下創(chuàng)建一個(gè)banzhang.txt,在banzhang.txt文件中增加“I love cls”。
$ touch batch.sh
$ vi batch.sh

在batch.sh中輸入如下內(nèi)容
#!/bin/bash

cd /home/xubh
touch cls.txt
echo "I love cls" >>cls.txt

3. Shell中的變量

系統(tǒng)變量

  1. 常用系統(tǒng)變量

HOME、PWD、SHELL、USER等

  1. 案例實(shí)操
# 查看系統(tǒng)變量的值
$ echo $HOME
/home/xubh

# 顯示當(dāng)前Shell中所有變量:set
$ set
BASH=/bin/bash
BASH_ALIASES=()
BASH_ARGC=()
BASH_ARGV=()

自定義變量

  1. 基本語(yǔ)法

    • 定義變量:變量=值
    • 撤銷變量:unset 變量
    • 聲明靜態(tài)變量:readonly變量,注意:不能unset
  2. 變量定義規(guī)則

    • 變量名稱可以由字母、數(shù)字和下劃線組成,但是不能以數(shù)字開(kāi)頭,環(huán)境變量名建議大寫
    • 等號(hào)兩側(cè)不能有空格
    • 在bash中,變量默認(rèn)類型都是字符串類型,無(wú)法直接進(jìn)行數(shù)值運(yùn)算。
    • 變量的值如果有空格,需要使用雙引號(hào)或單引號(hào)括起來(lái)。
  3. 案例實(shí)操

# (1)定義變量A
$ A=5
$ echo $A
5
#(2)給變量A重新賦值
$ A=8
$ echo $A
8
#(3)撤銷變量A
$ unset A
$ echo $A
#(4)聲明靜態(tài)的變量B=2,不能unset
$ readonly B=2
$ echo $B
2
$ B=9
-bash: B: readonly variable
#(5)在bash中,變量默認(rèn)類型都是字符串類型,無(wú)法直接進(jìn)行數(shù)值運(yùn)算
$ C=1+2
$ echo $C
1+2
#(6)變量的值如果有空格,需要使用雙引號(hào)或單引號(hào)括起來(lái)
$ D=I love banzhang
-bash: world: command not found
$ D="I love banzhang"
$ echo $A
I love banzhang
#(7)可把變量提升為全局環(huán)境變量,可供其他Shell程序使用
$ vim helloworld.sh 

在helloworld.sh文件中增加echo $B
#!/bin/bash

echo "helloworld"
echo $B

$ ./helloworld.sh 
Helloworld
# 發(fā)現(xiàn)并沒(méi)有打印輸出變量B的值。
$ export B
$ ./helloworld.sh 
helloworld
2

Array

像其它語(yǔ)言一樣,bash 也有數(shù)組類型。bash 中的數(shù)組是一個(gè)保存著很多值的變量,數(shù)組的長(zhǎng)度沒(méi)有限制,下標(biāo)也是從 0 開(kāi)始。在 bash 中有好幾種方法創(chuàng)建一個(gè)數(shù)組,如下所示。

Examples:

array[0] = val
array[1] = val
array[2] = val
array=([2]=val [0]=val [1]=val)
array=(val val val)

使用如下語(yǔ)法獲得數(shù)組特定位置的值:

${array[i]}     # i是數(shù)組下標(biāo)

如果沒(méi)有指定數(shù)組下標(biāo),默認(rèn)返回第一個(gè)元素。想知道數(shù)組中有多少個(gè)元素,使用下面的語(yǔ)法:

${#array[@]}

Bash 也支持三元運(yùn)算符,如下面的例子所示:

${varname:-word}    # 如果 varname 存在而且不為 null,返回它的值,否則返回 word
${varname:=word}    # 如果 varname 存在而且不為 null,返回它的值,否則把word賦值給它并且返回 word
${varname:+word}    # 如果 varname 存在而且不為 null,返回 word,否則返回 null
${varname:offset:length}    # 它返回 $varname 的子字符串,從 offset 處開(kāi)始,長(zhǎng)度為 length

String Substitution

${variable#pattern}         # 如果 pattern 匹配變量值的起始部分,刪除匹配 pattern 的最短的部分,然后返回剩余的
${variable##pattern}        # 如果 pattern 匹配變量值的起始部分,刪除匹配 pattern 的最長(zhǎng)的部分,然后返回剩余的
${variable%pattern}         # 如果 pattern 匹配變量值的結(jié)束部分,刪除匹配 pattern 的最短的部分,然后返回剩余的
${variable%%pattern}        # 如果 pattern 匹配變量值的結(jié)束部分,刪除匹配 pattern 的最長(zhǎng)的部分,然后返回剩余的
${variable/pattern/string}  # 把變量值中匹配 pattern 的最長(zhǎng)的部分替換為 string,只替換第一個(gè)匹配的部分
${variable//pattern/string} # 把變量值中匹配 pattern 的最長(zhǎng)的部分替換為 string,全局進(jìn)行替換
${#varname}     # 返回變量值作為一個(gè)字符串的長(zhǎng)度

特殊變量:$n

  1. 基本語(yǔ)法

? n (功能描述:n為數(shù)字,0代表該腳本名稱,1-9代表第一到第九個(gè)參數(shù),十以上的參數(shù),十以上的參數(shù)需要用大括號(hào)包含,如${10})

  1. 案例實(shí)操

    • 輸出該腳本文件名稱、輸入?yún)?shù)1和輸入?yún)?shù)2 的值
$ touch parameter.sh 
$ vim parameter.sh

#!/bin/bash
echo "$0  $1   $2"

$ chmod 777 parameter.sh
$ ./parameter.sh cls  xz
./parameter.sh  cls   xz

特殊變量:$#

  1. 基本語(yǔ)法

? $#(功能描述:獲取所有輸入?yún)?shù)個(gè)數(shù),常用于循環(huán))。

  1. 案例實(shí)操

    • 獲取輸入?yún)?shù)的個(gè)數(shù)
$ vim parameter.sh

#!/bin/bash
echo "$0  $1   $2"
echo $#

$ chmod 777 parameter.sh

$ ./parameter.sh cls  xz
parameter.sh cls xz 
2

特殊變量:*、@

  1. 基本語(yǔ)法

? * (功能描述:這個(gè)變量代表命令行中所有的參數(shù),*把所有的參數(shù)看成一個(gè)整體)

? @ (功能描述:這個(gè)變量也代表命令行中所有的參數(shù),不過(guò)@把每個(gè)參數(shù)區(qū)分對(duì)待)

  1. 案例實(shí)操

    • 打印輸入的所有參數(shù)
$ vim parameter.sh

#!/bin/bash
echo "$0  $1   $2"
echo $#
echo $*
echo $@

$ bash parameter.sh 1 2 3
parameter.sh  1   2
3
1 2 3
1 2 3

特殊變量:$?

  1. 基本語(yǔ)法

$? (功能描述:最后一次執(zhí)行的命令的返回狀態(tài)。如果這個(gè)變量的值為0,證明上一個(gè)命令正確執(zhí)行;如果這個(gè)變量的值為非0(具體是哪個(gè)數(shù),由命令自己來(lái)決定),則證明上一個(gè)命令執(zhí)行不正確了。)

  1. 案例實(shí)操

    • 判斷helloworld.sh腳本是否正確執(zhí)行
$ ./helloworld.sh 
hello world
$ echo $?
0

4. 運(yùn)算符

  1. 基本語(yǔ)法

    • ((運(yùn)算式))”或“[運(yùn)算式]”
    • expr + , - , *, /, % 加,減,乘,除,取余
  • 注意:expr運(yùn)算符間要有空格
  1. 案例實(shí)操:
#(1)計(jì)算3+2的值
$ expr 2 + 3
5
#(2)計(jì)算3-2的值
$ expr 3 - 2 
1
#(3)計(jì)算(2+3)X4的值
#(a)expr一步完成計(jì)算
$ expr `expr 2 + 3` \* 4
20
#(b)采用$[運(yùn)算式]方式
# S=$[(2+3)*4]
# echo $S

5. 條件判斷

  1. 基本語(yǔ)法

[ condition ](注意condition前后要有空格)

注意:條件非空即為true,[xubh]返回true,[] 返回false。

  1. 常用判斷條件
  • 兩個(gè)整數(shù)之間比較

= 字符串比較

-lt 小于(less than) -le 小于等于(less equal)

-eq 等于(equal) -gt 大于(greater than)

-ge 大于等于(greater equal) -ne 不等于(Not equal)

  • 按照文件權(quán)限進(jìn)行判斷

-r 有讀的權(quán)限(read)

-w 有寫的權(quán)限(write)

-x 有執(zhí)行的權(quán)限(execute)

  • 按照文件類型進(jìn)行判斷

-f 文件存在并且是一個(gè)常規(guī)的文件(file)

-e 文件存在(existence)

-d 文件存在并是一個(gè)目錄(directory)

  1. 案例實(shí)操
#(1)23是否大于等于22
$ [ 23 -ge 22 ]
$ echo $?
0
#(2)helloworld.sh是否具有寫權(quán)限
$ [ -w helloworld.sh ]
$ echo $?
0
#(3)/home/xubh/cls.txt目錄中的文件是否存在
$ [ -e /home/xubh/cls.txt ]
$ echo $?
1
#(4)多條件判斷(&& 表示前一條命令執(zhí)行成功時(shí),才執(zhí)行后一條命令,|| 表示上一條命令執(zhí)行失敗后,才執(zhí)行下一條命令)
$ [ condition ] && echo OK || echo notok
OK
$ [ condition ] && [ ] || echo notok
notok

6. 流程控制

if 判斷

  1. 基本語(yǔ)法
if [expression]; then
    will execute only if expression is true
else
    will execute if expression is false
fi

? 注意事項(xiàng):

  • [ 條件判斷式 ],中括號(hào)和條件判斷式之間必須有空格

  • if后要有空格

  1. 案例實(shí)操

    • 輸入一個(gè)數(shù)字,如果是1,則輸出banzhang zhen shuai,如果是2,則輸出cls zhen mei,如果是其它,什么也不輸出。
$ touch if.sh
$ vim if.sh

#!/bin/bash
if [ $1 -eq "1" ]
then
        echo "banzhang zhen shuai"
elif [ $1 -eq "2" ]
then
        echo "cls zhen mei"
fi

statement1 && statement2  # 兩個(gè)語(yǔ)句都為真
statement1 || statement2  # 至少一個(gè)語(yǔ)句為真

str1=str2       # str1 匹配 str2
str1!=str2      # str1 不匹配 str2
str1<str2       # str1 小于 str2
str1>str2       # str1 大于 str2
-n str1         # str1 不是 null (長(zhǎng)度大于 0)
-z str1         # str1 是 null (長(zhǎng)度為 0)

-a file         # 文件存在
-d file         # 文件存在而且是目錄
-e file         # 文件存在,跟 -a 一樣
-f file         # 文件存在,而且是常規(guī)文件(不是目錄或者其他特殊類型的文件)
-r file         # 你有讀權(quán)限
-s file         # 文件存在而且不為空
-w file         # 你有寫權(quán)限
-x file         # 你對(duì)文件有執(zhí)行權(quán)限,如果 file 是目錄的話,你對(duì)它有搜索權(quán)限
-N file         # 從上次讀之后文件被修改過(guò)
-O file         # 你是文件所有者
-G file         # 文件的 group ID 跟你的 group ID (或之一,如果你在很多分組里)相同

file1 -nt file2     # file1 比 file2 更新
file1 -ot file2     # file1 比 file2 更老

-lt     # 小于
-le     # 小于等于
-eq     # 等于
-ge     # 大于等于
-gt     # 大于
-ne     # 不等于

$ chmod 777 if.sh 
$ ./if.sh 1
banzhang zhen shuai

case 語(yǔ)句

  1. 基本語(yǔ)法

case $變量名 in

"值1")

? 如果變量的值等于值1,則執(zhí)行程序1

? ;;

"值2")

? 如果變量的值等于值2,則執(zhí)行程序2

? ;;

…省略其他分支…

*)

? 如果變量的值都不是以上的值,則執(zhí)行此程序

? ;;

esac

注意事項(xiàng):

  • case行尾必須為單詞“in”,每一個(gè)模式匹配必須以右括號(hào)“)”結(jié)束。
  • 雙分號(hào)“;;”表示命令序列結(jié)束,相當(dāng)于java中的break。
  • 最后的“*)”表示默認(rèn)模式,相當(dāng)于java中的default。
  1. 案例實(shí)操

    • 輸入一個(gè)數(shù)字,如果是1,則輸出banzhang,如果是2,則輸出cls,如果是其它,輸出renyao。
$ touch case.sh
$ vim case.sh

!/bin/bash

case $1 in
"1")
        echo "banzhang"
;;

"2")
        echo "cls"
;;
*)
        echo "renyao"
;;
esac

$ chmod 777 case.sh
$ ./case.sh 1
1

for 循環(huán)

  1. 基本語(yǔ)法1

for (( initialisation ; ending condition ; update ))
do
statements...
done
```

  1. 案例實(shí)操

    • 從1加到100
$ touch for1.sh
$ vim for1.sh

#!/bin/bash

s=0
for((i=0;i<=100;i++))
do
        s=$[$s+$i]
done
echo $s

$ chmod 777 for1.sh 
$ ./for1.sh 
“5050”
  1. 基本語(yǔ)法2
for name [in list]
do
  statements that can use $name
done
  1. 案例實(shí)操
    1. 打印所有輸入?yún)?shù)
$ touch for2.sh
$ vim for2.sh

#!/bin/bash
#打印數(shù)字

for i in $*
    do
      echo "ban zhang love $i "
    done

$ chmod 777 for2.sh 
$ bash for2.sh cls xz bd
ban zhang love cls
ban zhang love xz
ban zhang love bd
  1. 比較*和@區(qū)別

(a)*和@都表示傳遞給函數(shù)或腳本的所有參數(shù),不被雙引號(hào)“”包含時(shí),都以12 …$n的形式輸出所有參數(shù)。

$ touch for.sh
$ vim for.sh

#!/bin/bash 

for i in $*
do
      echo "ban zhang love $i "
done

for j in $@
do      
        echo "ban zhang love $j"
done

$ bash for.sh cls xz bd
ban zhang love cls 
ban zhang love xz 
ban zhang love bd 
ban zhang love cls
ban zhang love xz
ban zhang love bd

(b)當(dāng)它們被雙引號(hào)“”包含時(shí),“*”會(huì)將所有的參數(shù)作為一個(gè)整體,以“1 2 …n”的形式輸出所有參數(shù);“@”會(huì)將各個(gè)參數(shù)分開(kāi),以“1” “2”…”n”的形式輸出所有參數(shù)。

$ vim for.sh

#!/bin/bash 

for i in "$*" 
#$*中的所有參數(shù)看成是一個(gè)整體,所以這個(gè)for循環(huán)只會(huì)循環(huán)一次 
        do 
                echo "ban zhang love $i"
        done 

for j in "$@" 
#$@中的每個(gè)參數(shù)都看成是獨(dú)立的,所以“$@”中有幾個(gè)參數(shù),就會(huì)循環(huán)幾次 
        do 
                echo "ban zhang love $j" 
done

$ chmod 777 for.sh
$ bash for.sh cls xz bd
ban zhang love cls xz bd
ban zhang love cls
ban zhang love xz
ban zhang love bd

while 循環(huán)

  1. 基本語(yǔ)法
while condition; do
  statements
done
  1. 案例實(shí)操
    1. 從1加到100
$ touch while.sh
$ vim while.sh

#!/bin/bash
s=0
i=1
while [ $i -le 100 ]
do
        s=$[$s+$i]
        i=$[$i+1]
done

echo $s

$ chmod 777 while.sh 
$ ./while.sh 
5050

7. read讀取控制臺(tái)輸入

  1. 基本語(yǔ)法

? read(選項(xiàng))(參數(shù))

? 選項(xiàng):

-p:指定讀取值時(shí)的提示符;

-t:指定讀取值時(shí)等待的時(shí)間(秒)。

參數(shù)

? 變量:指定讀取值的變量名

  1. 案例實(shí)操

? (1)提示7秒內(nèi),讀取控制臺(tái)輸入的名稱

$ touch read.sh
$ vim read.sh

#!/bin/bash

read -t 7 -p "Enter your name in 7 seconds " NAME
echo $NAME

$ ./read.sh 
Enter your name in 7 seconds xiaoze
xiaoze

8. 函數(shù)

系統(tǒng)函數(shù)

  1. basename基本語(yǔ)法

basename [string / pathname] [suffix] (功能描述:basename命令會(huì)刪掉所有的前綴包括最后一個(gè)(‘/’)字符,然后將字符串顯示出來(lái)。

選項(xiàng):

suffix為后綴,如果suffix被指定了,basename會(huì)將pathname或string中的suffix去掉。

  1. 案例實(shí)操
  • 截取該/home/xubh/banzhang.txt路徑的文件名稱
$ basename /home/xubh/banzhang.txt 
banzhang.txt
$ basename /home/xubh/banzhang.txt .txt
banzhang
  1. dirname基本語(yǔ)法

? dirname 文件絕對(duì)路徑(功能描述:從給定的包含絕對(duì)路徑的文件名中去除文件名(非目錄的部分),然后返回剩下的路徑(目錄的部分))

  1. 案例實(shí)操

    • 獲取banzhang.txt文件的路徑
$ dirname /home/xubh/banzhang.txt 
/home/xubh

自定義函數(shù)

  1. 基本語(yǔ)法

[ function ] funname[()]

{

? Action;

? [return int;]

}

funname

  1. 經(jīng)驗(yàn)技巧

    ? 1.必須在調(diào)用函數(shù)地方之前,先聲明函數(shù),shell腳本是逐行運(yùn)行。不會(huì)像其它語(yǔ)言一樣先編譯。

    ? 2.函數(shù)返回值,只能通過(guò)$?系統(tǒng)變量獲得,可以顯示加:return返回,如果不加,將以最后一條命令運(yùn)行結(jié)果,作為返回值。return后跟數(shù)值n(0-255)

  2. 案例實(shí)操

    計(jì)算兩個(gè)輸入?yún)?shù)的和

$ touch fun.sh
$ vim fun.sh

#!/bin/bash
function sum()
{
    s=0
    s=$[ $1 + $2 ]
    echo "$s"
}

read -p "Please input the number1: " n1;
read -p "Please input the number2: " n2;
sum $n1 $n2;

$ chmod 777 fun.sh
$ ./fun.sh 
Please input the number1: 2
Please input the number2: 5
7
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • 官網(wǎng) 中文版本 好的網(wǎng)站 Content-type: text/htmlBASH Section: User ...
    不排版閱讀 4,435評(píng)論 0 5
  • 一、Python簡(jiǎn)介和環(huán)境搭建以及pip的安裝 4課時(shí)實(shí)驗(yàn)課主要內(nèi)容 【Python簡(jiǎn)介】: Python 是一個(gè)...
    _小老虎_閱讀 5,803評(píng)論 0 10
  • 什么是運(yùn)維 術(shù)語(yǔ)名詞 IDC--(Internet Data Center)互聯(lián)網(wǎng)數(shù)據(jù)中心,主要服務(wù)包括整機(jī)租用、...
    lyh165閱讀 2,751評(píng)論 0 19
  • 第 2 章 SHELL 基礎(chǔ)知識(shí)2.1 shell腳本我們?cè)谏厦婧?jiǎn)單介紹了一下什么是shell腳本,現(xiàn)在我們來(lái)進(jìn)一...
    LiWei_9e4b閱讀 1,591評(píng)論 0 0
  • Linux習(xí)慣問(wèn)題: 在vim編輯時(shí),按了ctrl + s后,再按ctrl + q就可以繼續(xù)執(zhí)行了。ctrl + ...
    光著腳的鞋閱讀 4,532評(píng)論 0 16