shell編程(一)

一、shell介紹
1.編程語言分類
2.shell簡介
3.shell腳本
1)什麼是shell腳本?
2)什麼時候用到腳本?
3)shell腳本能幹啥?
4)shell腳本的基本寫法
5)shell腳本的執行方法
二、變量的定義
1.變量是什麼?
2.什麼時候需要定義變量?
3.變量如何定義?
4.變量的定義規則
1)變量名區分大小寫
2)變量名不能有特殊符號
3)變量名不能以數字開頭
4)等號兩邊不能有任何空格
5)變量名儘量做到見名知意
5.變量的定義方式有哪些?
1)基本方式
2)命令執行結果賦值給變量
3)交互式定義變量(read)
4)定義有類型的變量(declare)
6.變量的分類
1)本地變量
2)環境變量
3)全局變量
4)系統變量
三、簡單四則運算
1.四則運算符號
2.瞭解i++和++i
四、擴展補充
1.數組定義
1)數組分類
2)普通數組定義
3)數組的讀取
4)關聯數組定義
2.其他變量定義

一、shell介紹

前言:

計算機只能認識(識別)機器語言(0和1),如(11000000 這種)。但是,我們的程序猿們不能直接去寫01這樣的代碼,所以,要想將程序猿所開發的代碼在計算機上運行,就必須找"人"(工具)來==翻譯成機器語言==,這個"人"(工具)就是我們常常所說的==編譯器==或者==解釋器==

shell編程(一)

1. 編程語言分類

  • 編譯型語言:

​ ==程序在執行之前需要一個專門的編譯過程==,把程序編譯成爲機器語言文件,運行時不需要重新翻譯,直接使用編譯的結果就行了。程序執行效率高,依賴編譯器,跨平臺性差些。如C、C++

  • 解釋型語言:

​ 程序不需要編譯,程序在運行時由==解釋器==翻譯成機器語言,每執行一次都要翻譯一次。因此效率比較低。比如Python/JavaScript/ Perl /ruby/==Shell==等都是解釋型語言。

shell編程(一)

  • 總結

編譯型語言比解釋型語言==速度較快==,但是不如解釋型語言==跨平臺性好==。如果做底層開發或者大型應用程序或者操作系開發一==般都用編譯型語言==;如果是一些服務器腳本及一些輔助的接口,對速度要求不高、對各個平臺的==兼容性有要求==的話則一般都用==解釋型語言==。

2. shell簡介

shell編程(一)

總結:

  • ==shell就是人機交互的一個橋樑==
  • shell的種類
[root@MissHou ~]# cat /etc/shells 
/bin/sh             #是bash的一個快捷方式
/bin/bash           #bash是大多數Linux默認的shell,包含的功能幾乎可以涵蓋shell所有的功能
/sbin/nologin       #表示非交互,不能登錄操作系統
/bin/dash           #小巧,高效,功能相比少一些

/bin/csh                #具有C語言風格的一種shell,具有許多特性,但也有一些缺陷
/bin/tcsh           #是csh的增強版,完全兼容csh

3. shell腳本

1)什麼是shell腳本?

  • 一句話概括

簡單來說就是將==需要執行的命令==保存到文本中,==按照順序執行==。它是解釋型的,意味着不需要編譯。

  • 準確敘述

若干命令 + 腳本的基本格式 + 腳本特定語法 + 思想= shell腳本

2)什麼時候用到腳本?

重複化、複雜化的工作,通過把工作的命令寫成腳本,以後僅僅需要執行腳本就能完成這些工作。

3)shell腳本能幹啥?

 ①自動化軟件部署   LAMP/LNMP/Tomcat... 

 ②自動化管理     系統初始化腳本、批量更改主機密碼、推送公鑰...

 ③==自動化分析處理==    統計網站訪問量

 ④==自動化備份==     數據庫備份、日誌轉儲...

 ⑤自動化監控腳本

4)shell腳本的基本寫法

1)腳本第一行,魔法字符==#!==指定解釋器【==必寫==】

#!/bin/bash 表示以下內容使用bash解釋器解析

==注意:==
如果直接將解釋器路徑寫死在腳本里,可能在某些系統就會存在找不到解釋器的兼容性問題,所以可以使用:#!/bin/env 解釋器

2)腳本第二部分,註釋(#號)說明,對腳本的基本信息進行描述【可選】

#!/bin/env bash

# 以下內容是對腳本的基本信息的描述
# Name: 名字
# Desc:描述describe
# Path:存放路徑
# Usage:用法
# Update:更新時間

#下面就是腳本的具體內容
commands
...

3)腳本第三部分,腳本要實現的具體代碼內容

5)shell腳本的執行方法

  • 標準腳本執行方法(建議)
1) 編寫人生第一個shell腳本
[root@MissHou shell01]# cat first_shell.sh
#!/bin/env bash

# 以下內容是對腳本的基本信息的描述
# Name: first_shell.sh
# Desc: num1
# Path: /shell01/first_shell.sh
# Usage:/shell01/first_shell.sh
# Update:2019-05-05

echo "hello world"
echo "hello world"
echo "hello world"

2) 腳本增加可執行權限
[root@MissHou shell01]# chmod +x first_shell.sh

3) 標準方式執行腳本
[root@MissHou shell01]# pwd
/shell01
[root@MissHou shell01]# /shell01/first_shell.sh
或者
[root@MissHou shell01]# ./first_shell.sh

注意:標準執行方式腳本必須要有可執行權限。
  • 非標準的執行方法(不建議)
  1. 直接在命令行指定解釋器執行
[root@MissHou shell01]# bash first_shell.sh
[root@MissHou shell01]# sh first_shell.sh
[root@MissHou shell01]# bash -x first_shell.sh
+ echo 'hello world'
hello world
+ echo 'hello world'
hello world
+ echo 'hello world'
hello world

-x:一般用於排錯,查看腳本的執行過程
-n:用來查看腳本的語法是否有問題
  1. 使用source命令讀取腳本文件,執行文件裏的代碼
[root@MissHou shell01]# source first_shell.sh
hello world
hello world
hello world

二、變量的定義

1. 變量是什麼?

一句話概括:變量是用來臨時保存數據的,該數據是可以變化的數據。

2. 什麼時候需要定義變量?

  • 如果某個內容需要多次使用,並且在代碼中重複出現,那麼可以用變量代表該內容。這樣在修改內容的時候,僅僅需要修改變量的值。
  • 在代碼運作的過程中,可能會把某些命令的執行結果保存起來,後續代碼需要使用這些結果,就可以直接使用這個變量。

3.變量如何定義?

變量名=====變量值

變量名:用來臨時保存數據的

變量值:就是臨時的可變化的數據

[root@MissHou ~]# A=hello           定義變量A
[root@MissHou ~]# echo $A           調用變量A,要給錢的,不是人民幣是美元"$"
hello
[root@MissHou ~]# echo ${A}     還可以這樣調用,不管你的姿勢多優雅,總之要給錢
hello
[root@MissHou ~]# A=world           因爲是變量所以可以變,移情別戀是常事
[root@MissHou ~]# echo $A           不管你是誰,只要調用就要給錢
world
[root@MissHou ~]# unset A           不跟你玩了,取消變量
[root@MissHou ~]# echo $A           從此,我單身了,你可以給我介紹任何人

4. 變量的定義規則

雖然可以給變量(變量名)賦予任何值;但是,對於==變量名==也是要求的!:unamused:

1)變量名區分大小寫

[root@MissHou ~]# A=hello
[root@MissHou ~]# a=world
[root@MissHou ~]# echo $A
hello
[root@MissHou ~]# echo $a
world

2)變量名不能有特殊符號

[root@MissHou ~]# *A=hello
-bash: *A=hello: command not found
[root@MissHou ~]# ?A=hello
-bash: ?A=hello: command not found
[root@MissHou ~]# @A=hello
-bash: @A=hello: command not found

特別說明:對於有空格的字符串給變量賦值時,要用引號引起來
[root@MissHou ~]# A=hello world
-bash: world: command not found
[root@MissHou ~]# A="hello world"
[root@MissHou ~]# A='hello world'

3)變量名不能以數字開頭

[root@MissHou ~]# 1A=hello
-bash: 1A=hello: command not found
[root@MissHou ~]# A1=hello
注意:不能以數字開頭並不代表變量名中不能包含數字呦。

4)等號兩邊不能有任何空格

[root@MissHou ~]# A =123
-bash: A: command not found
[root@MissHou ~]# A= 123
-bash: 123: command not found
[root@MissHou ~]# A = 123
-bash: A: command not found
[root@MissHou ~]# A=123
[root@MissHou ~]# echo $A
123

5)變量名儘量做到見名知意

NTP_IP=10.1.1.1
DIR=/u01/app1
TMP_FILE=/var/log/1.log
...

說明:一般變量名使用大寫(小寫也可以),不要同一個腳本中變量全是a,b,c等不容易閱讀

5. 變量的定義方式有哪些?

1)基本方式

直接賦值給一個變量

[root@MissHou ~]# A=1234567
[root@MissHou ~]# echo $A
1234567
[root@MissHou ~]# echo ${A:2:4}     表示從A變量中第3個字符開始截取,截取4個字符
3456

說明:
$變量名 和 ${變量名}的異同
相同點:都可以調用變量
不同點:${變量名}可以只截取變量的一部分,而$變量名不可以

2)命令執行結果賦值給變量

[root@MissHou ~]# B=`date +%F`
[root@MissHou ~]# echo $B
2019-04-16
[root@MissHou ~]# C=$(uname -r)
[root@MissHou ~]# echo $C
2.6.32-696.el6.x86_64

3)交互式定義變量(read)

目的:讓==用戶自己==給變量賦值,比較靈活。

語法:read [選項] 變量名

常見選項:

選項 釋義
-p 定義提示用戶的信息
-n 定義字符數(限制變量值的長度)
-s 不顯示(不顯示用戶輸入的內容)
-t 定義超時時間,默認單位爲秒(限制用戶輸入變量值的超時時間)

舉例說明:

用法1:用戶自己定義變量值
[root@MissHou ~]# read name
harry
[root@MissHou ~]# echo $name
harry
[root@MissHou ~]# read -p "Input your name:" name
Input your name:tom
[root@MissHou ~]# echo $name
tom

用法2:變量值來自文件
[root@MissHou ~]# cat 1.txt 
10.1.1.1 255.255.255.0

[root@MissHou ~]# read ip mask < 1.txt 
[root@MissHou ~]# echo $ip
10.1.1.1
[root@MissHou ~]# echo $mask
255.255.255.0

4)定義有類型的變量(declare)

目的:給變量做一些限制,固定變量的類型,比如:整型、只讀

用法:declare 選項 變量名=變量值

常用選項:

選項 釋義 舉例
==-i== 將變量看成整數 declare -i A=123
==-r== 定義只讀變量 declare -r B=hello
-a 定義普通數組;查看普通數組
-A 定義關聯數組;查看關聯數組
-x 將變量通過環境導出 declare -x AAA=123456 等於 export AAA=123456

舉例說明:

[root@MissHou ~]# declare -i A=123
[root@MissHou ~]# echo $A
123
[root@MissHou ~]# A=hello
[root@MissHou ~]# echo $A
0

[root@MissHou ~]# declare -r B=hello
[root@MissHou ~]# echo $B
hello
[root@MissHou ~]# B=world
-bash: B: readonly variable
[root@MissHou ~]# unset B
-bash: unset: B: cannot unset: readonly variable

6. 變量的分類

1)本地變量

  • ==本地變量==:當前用戶自定義的變量。當前進程中有效,其他進程及當前進程的子進程無效。

2)環境變量

  • 環境變量:當前進程有效,並且能夠被子進程調用。
    • env查看當前用戶的環境變量
    • set查詢當前用戶的所有變量(臨時變量與環境變量)
    • export 變量名=變量值 或者 變量名=變量值;export 變量名
[root@MissHou ~]# export A=hello        臨時將一個本地變量(臨時變量)變成環境變量
[root@MissHou ~]# env|grep ^A
A=hello

永久生效:
vim /etc/profile 或者 ~/.bashrc
export A=hello
或者
A=hello
export A

說明:系統中有一個變量PATH,環境變量
export PATH=/usr/local/mysql/bin:$PATH

3)全局變量

  • 全局變量:全局所有的用戶和程序都能調用,且繼承,新建的用戶也默認能調用.

  • 解讀相關配置文件
文件名 說明 備註
$HOME/.bashrc 當前用戶的bash信息,用戶==登錄==時讀取 定義別名、umask、函數等
$HOME/.bash_profile 當前用戶的環境變量,用戶==登錄==時讀取
$HOME/.bash_logout 當前用戶==退出==當前shell時最後讀取 定義用戶退出時執行的程序等
/etc/bashrc 全局的bash信息,所有用戶都生效
/etc/profile 全局環境變量信息 系統和所有用戶都生效
\$HOME/.bash_history 用戶的歷史命令 history -w 保存歷史記錄 history -c 清空歷史記錄

說明:以上文件修改後,都需要重新==source==讓其生效或者退出重新登錄。

  • 用戶登錄系統讀取相關==文件的順序==
    1. /etc/profile
    2. $HOME/.bash_profile
    3. $HOME/.bashrc
    4. /etc/bashrc
    5. $HOME/.bash_logout

4)系統變量

  • 系統變量(內置bash中變量) : shell本身已經固定好了它的名字和作用.
內置變量 含義
==$?== 上一條命令執行後返回的狀態;狀態值爲0表示執行正常,==非0==表示執行異常或錯誤
$0 當前執行的程序或腳本名
==$#== 腳本後面接的參數的==個數==
==$*== 腳本後面==所有參數==,參數當成一個整體輸出,每一個變量參數之間以空格隔開
==$@== 腳本後面==所有參數==,參數是獨立的,也是全部輸出
==\$1\~$9== 腳本後面的==位置參數==,$1表示第1個位置參數,依次類推
\${10}\~${n} 擴展位置參數,第10個位置變量必須用{}大括號括起來(2位數字以上擴起來)
==$$== 當前所在進程的進程號,如echo $$
$! 後臺運行的最後一個進程號 (當前終端)
!$ 調用最後一條命令歷史中的==參數==
  • 進一步瞭解位置參數$1~${n}
#!/bin/bash
#瞭解shell內置變量中的位置參數含義
echo "\$0 = $0"
echo "\$# = $#"
echo "\$* = $*"
echo "\$@ = $@"
echo "\$1 = $1" 
echo "\$2 = $2" 
echo "\$3 = $3" 
echo "\$11 = ${11}" 
echo "\$12 = ${12}" 
  • 進一步瞭解\$*和​\$@的區別

$*:表示將變量看成一個整體
$@:表示變量是獨立的

#!/bin/bash
for i in "$@"
do
echo $i
done

echo "======我是分割線======="

for i in "$*"
do
echo $i
done

[root@MissHou ~]# bash 3.sh a b c
a
b
c
======我是分割線=======
a b c

三、簡單四則運算

算術運算:默認情況下,shell就只能支持簡單的==整數==運算

運算內容:加(+)、減(-)、乘(*)、除(/)、求餘數(%)

1. 四則運算符號

表達式 舉例
$(( )) echo $((1+1))
$[ ] echo $[10-5]
expr expr 10 / 5
let n=1;let n+=1 等價於 let n=n+1

2.瞭解i++和++i

  • 對變量的值的影響
[root@MissHou ~]# i=1
[root@MissHou ~]# let i++
[root@MissHou ~]# echo $i
2
[root@MissHou ~]# j=1
[root@MissHou ~]# let ++j
[root@MissHou ~]# echo $j
2
  • 對==表達式==的值的影響
[root@MissHou ~]# unset i j
[root@MissHou ~]# i=1;j=1
[root@MissHou ~]# let x=i++         先賦值,再運算
[root@MissHou ~]# let y=++j         先運算,再賦值
[root@MissHou ~]# echo $i
2
[root@MissHou ~]# echo $j
2
[root@MissHou ~]# echo $x
1
[root@MissHou ~]# echo $y
2

四、擴展補充

1. 數組定義

1)數組分類

  • 普通數組:只能使用整數作爲數組索引(元素的下標)
  • 關聯數組:可以使用字符串作爲數組索引(元素的下標)

2)普通數組定義

  • 一次賦予一個值
數組名[索引下標]=值
array[0]=v1
array[1]=v2
array[2]=v3
array[3]=v4
  • 一次賦予多個值
數組名=(值1 值2 值3 ...)
array=(var1 var2 var3 var4)

array1=(`cat /etc/passwd`)          將文件中每一行賦值給array1數組
array2=(`ls /root`)
array3=(harry amy jack "Miss Hou")
array4=(1 2 3 4 "hello world" [10]=linux)

3)數組的讀取

${數組名[元素下標]}

echo ${array[0]}            獲取數組裏第一個元素
echo ${array[*]}            獲取數組裏的所有元素
echo ${#array[*]}           獲取數組裏所有元素個數
echo ${!array[@]}       獲取數組元素的索引下標
echo ${array[@]:1:2}    訪問指定的元素;1代表從下標爲1的元素開始獲取;2代表獲取後面幾個元素

查看普通數組信息:
[root@MissHou ~]# declare -a

4)關聯數組定義

①首先聲明關聯數組

declare -A asso_array1
declare -A asso_array2
declare -A asso_array3

② 數組賦值

  • 一次賦一個值
數組名[索引or下標]=變量值
# asso_array1[linux]=one
# asso_array1[java]=two
# asso_array1[php]=three
  • 一次賦多個值
# asso_array2=([name1]=harry [name2]=jack [name3]=amy [name4]="Miss Hou")
  • 查看關聯數組
# declare -A
declare -A asso_array1='([php]="three" [java]="two" [linux]="one" )'
declare -A asso_array2='([name3]="amy" [name2]="jack" [name1]="harry" [name4]="Miss Hou" )'
  • 獲取關聯數組值
# echo ${asso_array1[linux]}
one
# echo ${asso_array1[php]}
three
# echo ${asso_array1[*]}
three two one
# echo ${!asso_array1[*]}
php java linux
# echo ${#asso_array1[*]}
3
# echo ${#asso_array2[*]}
4
# echo ${!asso_array2[*]}
name3 name2 name1 name4
  • 其他定義方式
[root@MissHou shell05]# declare -A books
[root@MissHou shell05]# let books[linux]++
[root@MissHou shell05]# declare -A|grep books
declare -A books='([linux]="1" )'
[root@MissHou shell05]# let books[linux]++
[root@MissHou shell05]# declare -A|grep books
declare -A books='([linux]="2" )'

2. 其他變量定義

  • 取出一個目錄下的目錄和文件:dirnamebasename
# A=/root/Desktop/shell/mem.txt 
# echo $A
/root/Desktop/shell/mem.txt
# dirname $A   取出目錄
/root/Desktop/shell
# basename $A  取出文件
mem.txt
  • 變量"內容"的刪除和替換
一個“%”代表從右往左去掉一個/key/
兩個“%%”代表從右往左最大去掉/key/
一個“#”代表從左往右去掉一個/key/
兩個“##”代表從左往右最大去掉/key/

舉例說明:
# url=www.taobao.com
# echo ${#url}           獲取變量的長度
# echo ${url#*.}
# echo ${url##*.}
# echo ${url%.*}
# echo ${url%%.*}
  • 以下了解,自己完成
替換:/ 和 //
 1015  echo ${url/ao/AO}
 1017  echo ${url//ao/AO}   貪婪替換

替代: - 和 :-  +和:+
 1019  echo ${abc-123}
 1020  abc=hello
 1021  echo ${abc-444}
 1022  echo $abc
 1024  abc=
 1025  echo ${abc-222}

${變量名-新的變量值} 或者 ${變量名=新的變量值}
變量沒有被賦值:會使用“新的變量值“ 替代
變量有被賦值(包括空值): 不會被替代

 1062  echo ${ABC:-123}
 1063  ABC=HELLO
 1064  echo ${ABC:-123}
 1065  ABC=
 1066  echo ${ABC:-123}

${變量名:-新的變量值} 或者 ${變量名:=新的變量值}
變量沒有被賦值或者賦空值:會使用“新的變量值“ 替代
變量有被賦值: 不會被替代

 1116  echo ${abc=123}
 1118  echo ${abc:=123}

[root@MissHou ~]# unset abc
[root@MissHou ~]# echo ${abc:+123}

[root@MissHou ~]# abc=hello
[root@MissHou ~]# echo ${abc:+123}
123
[root@MissHou ~]# abc=
[root@MissHou ~]# echo ${abc:+123}

${變量名+新的變量值}
變量沒有被賦值或者賦空值:不會使用“新的變量值“ 替代
變量有被賦值: 會被替代
[root@MissHou ~]# unset abc
[root@MissHou ~]# echo ${abc+123}

[root@MissHou ~]# abc=hello
[root@MissHou ~]# echo ${abc+123}
123
[root@MissHou ~]# abc=
[root@MissHou ~]# echo ${abc+123}
123
${變量名:+新的變量值}
變量沒有被賦值:不會使用“新的變量值“ 替代
變量有被賦值(包括空值): 會被替代

[root@MissHou ~]# unset abc
[root@MissHou ~]# echo ${abc?123}
-bash: abc: 123

[root@MissHou ~]# abc=hello
[root@MissHou ~]# echo ${abc?123}
hello
[root@MissHou ~]# abc=
[root@MissHou ~]# echo ${abc?123}

${變量名?新的變量值}
變量沒有被賦值:提示錯誤信息
變量被賦值(包括空值):不會使用“新的變量值“ 替代

[root@MissHou ~]# unset abc
[root@MissHou ~]# echo ${abc:?123}
-bash: abc: 123
[root@MissHou ~]# abc=hello
[root@MissHou ~]# echo ${abc:?123}
hello
[root@MissHou ~]# abc=
[root@MissHou ~]# echo ${abc:?123}
-bash: abc: 123

${變量名:?新的變量值}
變量沒有被賦值或者賦空值時:提示錯誤信息
變量被賦值:不會使用“新的變量值“ 替代

說明:?主要是當變量沒有賦值提示錯誤信息的,沒有賦值功能

——————————本文到此結束,感謝閱讀————————————

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章