全套學習資料移步至公眾號【學神來啦】
本節所講內容:
??19.1 ?shell?基本語法
??19.2 ?SHELL變量及運用
??19.3 ?數學的運算
??19.4 ?實戰-升級系統中的java版本到1.8版本
更多學習資料點擊:
https://www.bilibili.com/video/BV12h411W7GM
19.1 ?shell 基本語法
19.1.1 ?什么是shell?
Shell是一個命令解釋器,它在操作系統的最外層,負責直接與用戶進行對話,把用戶的輸入解釋給操作系統,并處理各種各樣的操作系統的輸出結果,輸出到屏幕反饋給用戶。這種對話方式可以是交互式也可以是非交互式的
我們所輸入的命令計算機是不識別的,這時就需要一種程序來幫助我們進行翻譯,變成計算機能識別的二進制程序,同時又把計算機生成的結果返回給我們。
當前終端使用的哪種shell?
大多數linux發行版本默認shell使用的是bash
19.1.2 ?擴展:編程語言分類
編程語言主要用:低級語言和高級語言
1)低級語言:
機器語言:二進制語言
匯編語言:符號語言,使用助記符來代替操作碼,也就是用符號代替機器語言的二進制碼?
它們都是面向機器的語言
2)高級語言:
它是比較接近自然語言或者說人類語言的一種編程,用人們能夠容易理解的方式進行編寫程序,
靜態語言:編譯型語言?如:c?、?c++?、?java,
動態語言:解釋型語言?如:?php?、?shell?、?python?、??perl
gcc編譯器:(解釋器) ?將人類理解的語言翻譯成機器理解的語言
靜態語言和動態語言的區別:
靜態語言編譯時,變量的數據類型是確定的,靜態語言對硬件更友好,運行效率更高。
動態語言,運行時確定變量的數據類型,且運行時可改變變量的類型。動態語言更簡潔,對人類更友好,可以把更多精力放在業務邏輯上。
19.1.3 ?什么是SHELL腳本?
shell腳本:就是說我們把原來linux命令或語句放在一個文件中,然后通過這個程序文件去執行時,我們就說這個程序為shell腳本或shell程序;我們可以在腳本中輸入一系列的命令以及相關的語法語句組合,比如變量,流程控制語句等,把他們有機結合起來就形成了一個功能強大的shell腳本。
先手寫一個腳本體驗一下:
[root@xuegod63 ~]# vim test.sh???#寫入以下內容
#!/bin/bash
# This is shell.
echo "hello world"
mkdir /tmp/test
touch /tmp/test/a.txt
注釋:
1、!/bin/bash 作用:告訴腳本使用的是哪種命令解釋器。如不指shell,以當前shell作為執行的shell。
2、在shell中以#表示開頭,整個行就被當作一個注釋。執行時被忽略。
3、shell程序一般以.sh結尾
[root@xuegod63 ~]# chmod +x test.sh
[root@xuegod63 ~]# ./test.sh???#執行
hello world
創建shell程序的步驟:
§?第一步:創建一個包含命令和控制結構的文件。
§?第二步:修改這個文件的權限使它可以執行?!?使用chmod +x??test.sh
§?第三步:檢測語法錯誤??bash?-x abc.sh
§?第四步:執行?./example
shell腳本的執行通常有以下幾種方式
1、/root/test.sh ?或者 ./test.sh (當前路徑下執行腳本的話要有執行權限chmod +x test.sh)
2、bash test.sh 或 sh test.sh ?(這種方式可以不對腳本文件添加執行權限)
3、source test.sh (可以沒有執行權限)???. ?test.sh
4、sh < test.sh 或者 cat test.sh |sh(bash)
19.2 ?SHELL變量及運用
19.2.1 ?shell變量
變量是shell 傳遞數據的一種方法。變量是用來代表每個值的符號名。我們可以把變量當成一個容器,通過變量,可以在內存中存儲數據。也可以在腳本執行中進行修改和訪問存儲的數據
變量的設置規則:
1.變量名稱通常是大寫字母,它可以由數字、字母(大小寫)和下劃線_組成。變量名區分大小寫;但是大家要注意變量名稱不能以數字開頭
2.等號 = 用于為變量分配值,在使用過程中等號兩邊不能有空格
3.變量存儲的數據類型是整數值和字符串值
4.在對變量賦于字符串值時,建議大家用引號將其括起來。因為如果字符串中存在空格符號。需要使用單引號或雙引號
5.要對變量進行調用,可以在變量名稱前加美元符號$
6.如果需要增加變量的值,那么可以進行變量值的疊加。不過變量需要用雙引號包含“變量名”或用變量名”或用{變量名}包含
變量的分類
按照變量的作用可以分成4類:
1、用戶自定義變量
2、環境變量:這種變量中主要保存的是和系統操作環境相關的數據。
3、位置參數變量:這種變量主要是用來向腳本當中傳遞參數或數據的,變量名不能自定義,變量作用是固定的。1 ?1?2 ?…
4、預定義變量:是Bash中已經定義好的變量,變量名不能自定義,變量作用也是固定的。
按照變量作用域可以分成2類:全局變量和局部變量。
局部變量是shell 程序內部定義的,其使用范圍僅限于定義它的程序,對其它程序不可見。包括:用戶自定義變量、位置變量和預定義變量。
全局變量是環境變量,其值不隨shell 腳本的執行結束而消失。
19.2.2 ?用戶定義變量
變量名命名規則:由字母或下劃線打頭,不允許數字開頭,后面由字母、數字或下劃線組成,并且大小寫字母意義不同。在使用變量時,在變量名前加$
例1:給變量var1賦值
[root@xuegod63 ~]# var1=123
[root@xuegod63 ~]# echo?$var1
123
variable???[?ve?ri?bl]??變量
例2:錯誤的賦值方式,不允許數字開頭,等號兩邊不能有空格
[root@xuegod63 ~]# var2 =456
bash: var2: 未找到命令...
[root@xuegod63 ~]# var2= 456
bash: 456: 未找到命令...
[root@xuegod63 ~]# var2 = 456
bash: var2: 未找到命令...
[root@xuegod63 ~]# 3var2 = 456
bash: 3var2: 未找到命令...
例3:變量值的疊加,使用${}
name是name是{name}的簡化版本,但是在某些情況下,還必須使用花括號引起的方式來消除歧義并避免意外的結果
[root@xuegod63 ~]# var4=mysql
[root@xuegod63 ~]# echo?$var4
mysql
[root@xuegod63 ~]# echo?$var4-db.log
mysql-db.log
[root@xuegod63 ~]# echo?$var4.db.log
mysql.db.log
[root@xuegod63 ~]# echo?$var4db.log???#發現輸出的結果不是我們想要的,怎么辦?
.log
[root@xuegod63 ~]# echo?${var4}db.log
mysqldb.log
19.2.3 ?命令的替換,使用$()或反引號
例1: 在命令中調用date命令輸出值
[root@xuegod63 ~]# echo `date`
2018年 05月 25日 星期五 17:41:29 CST
[root@xuegod63 ~]# echo?$(date)
2018年 05月 25日 星期五 17:41:42 CST
[root@xuegod63 ~]# echo `date +"%Y-%m-%d"`
2012-05-23
[root@xuegod63 ~]# echo `date +%F`
2012-05-23
[root@xuegod63 ~]# echo?$(date +%F)
2012-05-23
分享一個系統時間錯誤,引起tar報警告
[root@xuegod63 ~]# date -s "2012-03-03 21:25:00"
[root@xuegod63 ~]# tar czvf root.tar.gz /root/.cache/tracker/db-version.txt && tar xvf root.tar.gz -C /opt/
root/.cache/tracker/db-version.txt
tar: root/.cache/tracker/db-version.txt:時間戳 2017-09-19 13:05:18 是未來的 168094624.438537189 秒之后
注: 如果彈出這個消息,是因為咱們的當前系統的時間不對。 比如:當前系統的時間晚于文件的mtime時間
[root@xuegod83 ~]# hwclock -s #以硬件時間為基準,修改系統時間
19.2.4??shell中單引號和雙引號區別
‘’?在單引號中所有的字符包括特殊字符($,'',`和\)都將解釋成字符本身而成為普通字符(所見即所得)。
“”?在雙引號中,除了$, '', `反引號和\以外所有的字符都解釋成字符本身,擁有“調用變量的值”、“引用命令”和“轉義符”的特殊含義
注:\轉義符,跟在\之后的特殊符號將失去特殊含義,變為普通字符。如\將輸出“將輸出“”符號,而不當做是變量引用
例:
[root@xuegod63 ~]# echo?$var1
123
[root@xuegod63 ~]# echo \$var1
$var1
例1:給變量值賦于多個單詞,需要使用單引號和雙引號
[root@xuegod63 ~]# var8='xuegod?user1'
[root@xuegod63 ~]# echo?$var8
xuegdo user1
例2:賦值時單引號和雙引號的區別
[root@xuegod63 ~]# var8='xuegod user1?$var1'
[root@xuegod63 ~]# var9="xuegod user1?$var1"???#雙引中$符號有作用
[root@xuegod63 ~]# echo?$var8
xuegod user1?$var1
[root@xuegod63 ~]# echo?$var9
xuegod user1 123
注:單引號之間的內容原封不動賦值給變量,雙引號之間的內容如有特殊符號會保留它的特殊含義
例?3:賦值時單引號和雙引號的區別
[root@xuegod63 ~]# vim var.sh
#!/bin/bash
var=88
echo "$var"
echo '$var'
echo "'$var'"
echo '"$var"'
當單獨使用雙引號時,可以取出變量值
當單獨使用單引號時,不能取出變量值
當外層使用雙引號時,輸出內層的單引號和變量值
當外層使用單引號時,輸出內層的雙引號和雙引號中的內容。
刪除變量
[root@xuegod63 ~]# unset var1
[root@xuegod63 ~]# echo?$var1
19.2.5??環境變量
在bash shell中,變量分為兩類:全局變量和局部變量
全局變量:對于shell會話和所有的子shell都是可見的
局部變量: 它只在自己的進程當中使用
例1:局部變量
[root@xuegod63 ~]# var1=111
[root@xuegod63 ~]# var2=222
[root@xuegod63 ~]# echo?$var1
111
[root@xuegod63 ~]# vim a.sh
#!/bin/bash
echo?$var1
echo?$var2
[root@xuegod63 ~]# echo?$var1$var2
111 222
[root@xuegod63 ~]# bash a.sh???#執行a.sh 時,會使用另一個bash去執行,就訪問不到$var1和var2的值
例2:使用export把這個var1局部變量輸出為全局變量
[root@xuegod63 ~]#??export??var1=xuegod
[root@xuegod63 ~]#?echo?$var1?$var2
xuegod 222
[root@xuegod63 ~]# cat a.sh
#!/bin/bash
echo?$var1
echo?$var2
[root@xuegod63 ~]# bash a.sh???#引用全局變量var1成功
xuegod
env環境變量???全局變量
雖然我們設置了export全局變量,但是新開的xshell連接中,還是讀不到變量var1,怎么辦?
例3:讓變量永久生效,可以把定義好的變量寫入配置文件
當登錄系統或新開啟一個ssh連接啟動bash進程時,一定會加載這4個配置文件:
[root@xuegod63 ~]# vim /etc/profile????#系統全局環境和登錄系統的一些配置
[root@xuegod63 ~]# vim /etc/bashrc ???#bash全局自義配置文件,用于自定義shell
[root@xuegod63 ~]# vim /root/.bashrc???#用于單獨自定義某個用戶的bash
[root@xuegod63 ~]# vim /root/.bash_profile??#用戶單獨自定義某個用戶的系統環境
下面開始插入永久變量:
[root@xuegod63 ~]# vim /etc/profile???#在文件的最后插入
export var1=xuegod?????#=等號兩邊不能有空格
[root@xuegod63 ~]# source ?/etc/profile???#重新加載profile文件
新打開的鏈接中,也有了
如何知道新建一個ssh連接,加載這4個配置文件先后順序?
答:可以每個文件的最后,追加一個echo命令,輸出一下文件的名字
[root@xuegod63 ~]# echo 'echo??/etc/profile ' >>?/etc/profile
[root@xuegod63 ~]# echo 'echo??/etc/bashrc' >> /etc/bashrc
[root@xuegod63 ~]# echo 'echo??/root/.bashrc ' >> /root/.bashrc
[root@xuegod63 ~]# echo 'echo??/root/.bash_profile?' >> /root/.bash_profile
[root@xuegod63 ~]# ssh root@192.168.1.63???#彈出以下信息,就知道有優先級了
/etc/profile
/etc/bashrc
/root/.bashrc ?這個文件會判斷/etc/bashrc是否存在,存在則激活
/root/.bash_profile
19.2.6??設置PATH環境變量
SHELL要執行某一個程序,它要在系統中去搜索這個程序的路徑,PATH變量是用來定義命令和查找命令的目錄,當我們安裝了第三方程序后,可以把第三方程序bin目錄添加到這個path路徑內,就可以在全局調用這個第三方程序了
例1:
[root@xuegod63 ~]# vim /opt/backup ??????????????????
#!/bin/bash
echo "Backup data is OK!"
[root@xuegod63 ~]# chmod +x /opt/backup ??
[root@xuegod63 ~]# /opt/backup
[root@xuegod63 ~]# backup
bash: backup: 未找到命令...
將backup命令添加PATH中
[root@xuegod63 ~]# echo?$PATH
[root@xuegod63 ~]# PATH=/opt/:$PATH
[root@xuegod63 ~]# echo?$PATH
[root@xuegod63 ~]# backup???#發現命令可以直接執行了,不用寫全路徑了
[root@xuegod63 ~]# vim /etc/profile??# 在文件最后追加以下內容,永久生效
export PATH=/opt/:$PATH
[root@xuegod63 ~]# source ?/etc/profile???#重新加載配置文件,使用配置生效
19.2.7??shell位置變量
Shell解釋執行用戶的命令時,將命令行的第一個字符作為命令名,而其它字符作為參數。 ?
$0 ?獲取當前執行shell腳本文件的文件名,包括腳本路徑,命令本身
n ?獲取當前腳本的第n個參數 n=1,2.....n 當n大于9時 用n?獲取當前腳本的第n個參數n=1,2.....n當n大于9時用{10}表示。
例子:
[root@xuegod63 ~]# vim print.sh??
#!/bin/bash
echo "本shell腳本的文件名:?$0"
echo "第1個參數: ?$1"
echo "第2個參數: ?$2"
echo "第3個參數: ?$3"
echo "第4個參數: ?$4"
[root@xuegod63 ~]# chmod +x print.sh
[root@xuegod63 ~]# ./print.sh 111 ?222 a.txt ?444
本shell腳本的文件名: ./print.sh
第1個參數: ?111
第2個參數: ?222
第3個參數: ?a.txt
第4個參數: ?444
使用場景:服務器啟動傳參數
[root@xuegod63 ~]# /etc/init.d/network restart
19.2.8??特殊變量(預定義變量)
有些變量是一開始執行Script腳本時就會設定,且不能被修改,但我們不叫它只讀的系統變量,而叫它特殊變量。這些變量當執行程序時就有了,以下是一些特殊變量:
$*以一個單字符串顯示所有向腳本傳遞的參數;
如"*"用【"】括起來的情況、以"?"用【"】括起來的情況、以"1?2 …2…n"的形式輸出所有參數
$#傳遞到腳本的參數個數
當前進程的進程號PID??腳本運行的當前 進程ID號
$?顯示最后命令的退出狀態;0表示沒有錯誤,其他任何值表明有錯誤
$!后臺運行的最后一個進程的進程號pid
[root@xuegod63 ~]# vim test_var.sh
#!/bin/bash
echo "$* 一個字符串顯示這個程序的所有參數"
echo "$# 表示這個程序的參數個數"
touch /tmp/a.txt
echo "?表示當前進程的進程號PID"
touch /tmp/b.txt &
echo "$! 表示上一個后臺運行的進程的PID"
echo "$? 表示上一個程序執行返回結果"
[root@xuegod63 ~]# bash test_var.sh ?1 2 3 4 5
1 2 3 4 5 表示這個程序的所有參數
5 表示這個程序的參數個數
22385 表示當前進程的進程號PID
22387 表示上一個后臺運行的進程的PID
0 表示上一個程序執行返回結果
例2:常用的環境變量
[root@xuegod63 ~]# cd /opt
[root@xuegod63 opt]# vim env.sh
#!/bin/bash
echo \HOME變量值是HOME變量值是HOME
echo \PATH變量值是PATH變量值是PATH
echo \PWD變量值是PWD變量值是PWD?
[root@xuegod63 opt]# bash env.sh
$HOME變量值是/root
$PATH變量值是/opt/:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
$PWD變量值是/opt
declare 聲明變量類型
declare [+/-] [選項] 變量名
- : 給變量設定類型屬性
+: 取消給變量設定類型屬性
-i 將變量聲明為整數型
-x 將變量聲明為環境變量 等同于exprot
-r 將變量聲明為只讀變量
-p 顯示指定變量的被聲明類型
[root@xuegod83 ~]# declare -i num
[root@xuegod83 ~]# num=1
[root@xuegod83 ~]# echo?$num
1
[root@xuegod83 ~]# num=abc
[root@xuegod83 ~]# echo?$num
0
[root@xuegod83 ~]# declare +i num
[root@xuegod83 ~]# num=abc
[root@xuegod83 ~]# echo?$num
abc
[root@xuegod83 ]# a=123
[root@xuegod83 ]# b=456
[root@xuegod83 ]# c=a+a+b
[root@xuegod83 ]# echo?$c
123+456
[root@xuegod83 ]# declare -i c=a+a+b
[root@xuegod83 ]# echo?$c
579
[root@xuegod83 ~]# declare -x abc
[root@xuegod83 ~]# abc=123
[root@xuegod83 ~]# env | grep abc
abc=123
19.3 ?數學的運算
19.3.1 ?expr命令
(1)對數字的基本計算,做比較時,輸出結果假為0,1為真;特殊符號用轉義符
[root@xuegod63 ~]# expr 2 \> 5
0
[root@xuegod63 ~]# expr 6 \> 5
1
[root@xuegod63 ~]# expr 3 * 5
expr: 語法錯誤
[root@xuegod63 ~]# expr 3 \* 5
15
[root@xuegod63 ~]# expr 3 \+ 5·
8
(2)對字符串的處理
[root@xuegod63 ~]# expr length "ni hao"
6
[root@xuegod63 ~]# expr substr "ni hao" 2 4??#從第2個開始,截取4個字符出來
i ha
字符串提取
第一種模式:{var:num},這種模式時,shell在var中提取第n個字符到末尾的所有字符。若n為正數,從左邊0處開始;若n為負數,從右邊開始提取字串,但必須使用在冒號后面加空格或整個n加上小括號,如var:num,這種模式時,shell在var中提取第n個字符到末尾的所有字符。若n為正數,從左邊0處開始;若n為負數,從右邊開始提取字串,但必須使用在冒號后面加空格或整個n加上小括號,如{var: -2}、${var:(-2)}。
[root@xuegod63?~]#?var=http://www.xuegod.cn/123.htm
[root@xuegod63 ~]# echo?${var:5}
[root@xuegod63 ~]# echo?${var: -5}
3.htm
[root@xuegod63 ~]# echo?${var:(-5)}
3.htm
第二種模式:{var:n1:n2},n1是位置,n2是長度。表示從var:n1:n2,n1是位置,n2是長度。表示從var字符串的第n1個位置開始提取長度為n1個位置開始提取長度為n2的子串。不能為負數。
[root@xuegod63 ~]# echo?${var:0:5}
http:
[root@xuegod63 ~]# echo?${var:1:5}
ttp:/
[root@xuegod63 ~]# echo?${var:7:13}
字符串替換:
第一種模式:${var/pattern/pattern}表示將var字符串的第一個匹配的pattern替換為另一個pattern。
[root@xuegod63 ~]# echo?${var/cn/com}
第二種模式:${var//pattern/pattern}表示將var字符串中的所有能匹配的pattern替換為另一個pattern。
[root@xuegod63 ~]# echo?${var/w/o}
[root@xuegod63 ~]# echo?${var//w/opt}
http://optoptopt.xuegod.cn/123.htm
% 是去掉右邊,最小匹配
${variable%pattern},這種模式時,shell在variable中查找,看它是否符合pattern,如果是,就把variable中的內容去掉右邊最小的匹配
[root@xuegod63 ~]# echo?${var%/*m}
%% 是去掉右邊,最大匹配
${variable%%pattern},這種模式時,shell在variable中查找,看它是否符合pattern,如果是,就把variable中的內容去掉右邊最大的匹配
[root@xuegod63 ~]# echo?${var%%/*m}
http:
[root@xuegod63 ~]# echo?${var%w*m} ???????#最短匹配
http://ww
[root@xuegod63 ~]# echo?${var%%w*m} ?????#最長匹配
http://
# 是去掉左邊,最小匹配
[root@xuegod63 ~]# echo?${var#*w}
ww.xuegod.cn/123.htm
## 是去掉左邊,最大匹配
[root@xuegod63 ~]# echo?${var##*w}
.xuegod.cn/123.htm
[root@xuegod63 ~]# echo?${var#*/}
[root@xuegod63 ~]# echo?${var##*/}
123.htm
互動:如何取中間的www.xuegod.cn?
[root@xuegod63 ~]# a=${var#*//}
[root@xuegod63 ~]# echo?$a
[root@xuegod63 ~]# a=${a%/*}
[root@xuegod63 ~]# echo?$a
19.3.2 ?$(( ))應用
格式:$((表達式1,表達2))
特點:
1、在雙括號結構中,所有表達式可以像c語言一樣,如:a++,b--等。a++ ?等價于 a=a+1
2、在雙括號結構中,所有變量可以不加入:“$”符號前綴。
3、雙括號可以進行邏輯運算,四則運算
4、雙括號結構 擴展了for,while,if條件測試運算
5、支持多個表達式運算,各個表達式之間用“,”分開
常用的算數運算符
運算符?????意義
++ ??--?遞增及遞減,可前置也可以后置
+ ?- ?! ~?一元運算的正負號 邏輯與取反
+ ?- ?* ?/ ??%?加減乘除與余數
< ??<= ??> ??>=?比較大小符號
== ??!=?相等 不相等
>> ?<<?向左位移 向右位移
& ^ ??|?按位的與 按位的異或 按位的或
&& ?||?邏輯與 邏輯或
? :?條件判斷
1:
[root@xuegod63 opt]# b=$((1+2))
[root@xuegod63 opt]# echo?$b
3
[root@xuegod63 opt]# echo?$((2*3))
6
例2:遞增和遞減
[root@xuegod63 opt]# echo?$((++b))
6
說明: a++或a--為先賦值再+1或減1 ?; ?++a或--a為先加1或減1,然后再進行賦值
[root@xuegod63 ~]# a=1
[root@xuegod63 ~]# for i in {1..10}; ?do echo?$((a++)); done;
[root@xuegod63 ~]# a=1
[root@xuegod63 ~]# for i in {1..10}; ?do echo?$((++a)); done;
[root@xuegod63 ~]# a=1;b=
[root@xuegod63 ~]# echo?a,a,b
[root@xuegod63 ~]# ((a=a+b,b=a,c=4*5))
[root@xuegod63 ~]# echo?a,a,b,$c
19.4 ?實戰-升級系統中的java版本到1.8版本
上傳jdk-8u231-linux-x64.rpm軟件包到xuegod63
[root@xuegod63 ~]# rpm -ivh jdk-8u231-linux-x64.rpm
[root@xuegod63 ~]# rpm -qpi jdk-8u231-linux-x64.rpm #通過查看jdk的信息可以知道jdk的安裝目錄在/usr/java
[root@xuegod63 ~]#vim?/etc/profile???#在文件的最后添加以下內容:
export JAVA_HOME=/usr/java/jdk1.8.0_231-amd64
export JAVA_BIN=${JAVA_HOME}/bin
export PATH={JAVA_BIN}:JAVABIN:PATH
export CLASSPATH=.:{JAVA_HOME}/lib/dt.jar:JAVAHOME/lib/dt.jar:{JAVA_HOME}/lib/tools.jar
[root@xuegod63 ~]#source /etc/profile #使配置文件生效
[root@xuegod63 ~]# env | grep jav
驗證java運行環境是否安裝成功:
[root@xuegod63 ~]# ?java -version
java version "1.8.0_231"
Java(TM) SE Runtime Environment (build 1.8.0_231-b11)
Java HotSpot(TM) 64-Bit Server VM (build 25.231-b11, mixed mode)
如果出現安裝的對應版本,說明java運行環境已經安裝成功。
注:這里只是升級了jdk的版本,因為在我安裝的系統中已經安裝了jdk。
更多學習內容請移步至公眾號【學神來啦】