Centos7.5-shell指令碼的基礎
本節所講內容:
- 19.1 shell 基本語法
- 19.2 SHELL變數及運用
- 19.3 數學運算
- 19.4 實戰-升級系統中的java版本到1.8版本-為後期安裝Hadoop叢集做準備
19.1 shell 基本語法 19.1.1 什麼是shell?
Shell是一個命令直譯器,它在作業系統的最外層,負責直接與使用者進行對話,把使用者的輸入解釋給作業系統,並處理各種各樣的作業系統的輸出結果,輸出到螢幕反饋給使用者。這種對話方式可是互動也可以是非互動式的
**我們所輸入的命令計算機是不識別的,這時就需要一種程式來幫助我們進行翻譯,變成計算機能識別的二進位制程式,同時又把計算機生成的結果返回給我們。**
19.1.2 程式語言分類
程式語言主要用:低階語言和高階語言
-
1)低階語言: 機器語言:二進位制語言 組合語言:符號語言,使用助記符來代替操作碼,也就是用符號代替機器語言的二進位制碼 它們都是面向機器的語言
-
2)高階語言: 它是比較接近自然語言或者說人類語言的一種程式設計,用人們能夠容易理解的方式進行編寫程式,
-
靜態語言:編譯型語言 如:c 、 c++ 、 java,
-
動態語言:解釋型語言 如: php 、 shell 、 python 、 perl
-
gcc編譯器:(直譯器) 將人類理解的語言翻譯成機器理解的語言
19.1.3 什麼是SHELL指令碼?
shell指令碼:就是說我們把原來linux命令或語句放在一個檔案中,然後通過這個程式檔案去執行時,我們就說這個程式為shell指令碼或shell程式;我們可以在指令碼中輸入一系統的命令以及相關的語法語句組合,比如變數,流程控制語句等,把他們有機結合起來就形成了一個功能強大的shell指令碼
先手寫一個指令碼體驗一下:
[[email protected] ~]# 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結尾
[[email protected] ~]# chmod +x test.sh
[ [email protected] ~]# ./test.sh #執行
hello world
建立shell程式的步驟:
第一步:建立一個包含命令和控制結構的檔案。
第二步:修改這個檔案的許可權使它可以執行。 使用chmod +x test.sh
第三步:檢測語法錯誤
第四步:執行 ./example
shell指令碼的執行通常有以下幾種方式
1、/root/test.sh 或者 ./test.sh (當前路徑下執行指令碼的話要有執行許可權chmod +x test.sh)
2、bash test.sh 或 sh test.sh (這種方式可以不對指令碼檔案新增執行許可權)
3、source test.sh (可以沒有執行許可權)
4、sh < test.sh 或者 cat test.sh |sh(bash)
Linux架構師高薪入口: 1.學神IT教育官方網站: http://xuegod.ke.qq.com 2.10年行業資深老鳥MK:QQ2659153446 3.加入Linux技術交流QQ群:722287089,即可獲得以下福利: ①定期分享免費學習資料與視訊(工具+筆記+拓展實戰) ②10年行業資深老鳥線上答疑:技能+實戰+專案分享+高薪就業 ③有機會免費領取Linux雲端計算叢集架構師4冊書籍
19.2 SHELL變數及運用
19.2.1 shell變數
變數是shell 傳遞資料的一種方法。變數是用來代表每個值的符號名。我們可以把變數當成一個容器,通過變數,可以在記憶體中儲存資料。也可以在指令碼執行中進行修改和訪問儲存的資料 變數的設定規則: 1、 變數名稱通常是大寫字母,它可以由數字、字母(大小寫)和下劃線_組成。變數名區分大小寫;但是大家要注意變數名稱不能以數字開頭 2、 等號 = 用於為變數分配值,在使用過程中等號兩邊不能有空格 3、 變數儲存的資料型別是整數值和字串值 4、 在對變數賦於字串值時,建議大家用引號將其括起來。因為如果字串中存在空格隔符號。需要使用單引號或雙引號 5、 要對變數進行呼叫,可以在變數名稱前加美元符號$ 6、 如果需要增加變數的值,那麼可以進行變數值的疊加。不過變數需要用雙引號包含“{變數名}包含
變數的分類 按照變數的作用可以分成4類: 1、使用者自定義變數 2、環境變數:這種變數中主要儲存的是和系統操作環境相關的資料。 3位置引數變數:這種變數主要是用來向腳本當中傳遞引數或資料的,變數名不能自定義,變數作用是固定的。 4、預定義變數:是Bash中已經定義好的變數,變數名不能自定義,變數作用也是固定的。 按照變數作用域可以分成2類:全域性變數和區域性變數。 區域性變數是shell 程式內部定義的,其使用範圍僅限於定義它的程式,對其它程式不可見。包括:使用者自定義變數、位置變數和預定義變數。 全域性變數是環境變數,其值不隨shell 指令碼的執行結束而消失。
19.2.2 使用者定義變數
變數名命名規則:由字母或下劃線打頭,不允許數字開頭,後面由字母、數字或下劃線組成,並且大小寫字母意義不同。在使用變數時,在變數名前加$
例1:給變數VAR1賦值
[[email protected] ~]# VAR1=123
[[email protected] ~]# echo $VAR1
123
variable [ˈveəriəbl] 變數
例2:錯誤的賦值方式,不允許數字開頭,等號兩邊不能有空格
[[email protected] ~]# VAR2 =456
bash: VAR2: 未找到命令...
[[email protected] ~]# VAR2= 456
bash: 456: 未找到命令...
[[email protected] ~]# VAR2 = 456
bash: VAR2: 未找到命令...
[[email protected] ~]# 3VAR2 = 456
bash: 3VAR2: 未找到命令...
例3:變數值的疊加,使用${}
$name是${name}的簡化版本,但是在某些情況下,還必須使用花括號引起的方式來消除歧義並避免意外的結果
[[email protected] ~]# VAR4=mysql
[[email protected] ~]# echo $VAR4
mysql
[[email protected] ~]# echo $VAR4-db.log
mysql-db.log
[[email protected] ~]# echo $VAR4.db.log
mysql.db.log
[[email protected] ~]# echo $VAR4db.log #發現輸出的結果不是我們想要的,怎麼辦?
.log
[[email protected] ~]# echo ${VAR4}db.log
mysqldb.log
19.2.3 命令的替換,使用$()或反引號
例1:在命令就呼叫date命令
擴充套件:date命令是顯示或設定系統時間與日期。
-s<字串>:根據字串來設定日期與時間。字串前後必須加上雙引號;
<+時間日期格式>:指定顯示時,使用特定的日期時間格式。
例:格式化輸出:
[[email protected] ~]# date +"%Y-%m-%d" #今天時間,一般備份資料需要用這個
2018-05-25
[[email protected] ~]# date +"%Y-%m" #只顯示年月
2018-05
[[email protected] ~]# date +"%Y-%m-%d %H:%M.%S" #日期加時間
2018-05-25 17:51.36
[[email protected] ~]# date +"%Y/%m/%d %H/%M/%S" #使用/做分隔符
2018-05-25 17-51-43
[[email protected] ~]# date +"%Y-%m-%d-%H-%M-%S" #使用-做分隔符,一般備份資料需要用這個
注: %y 年份只顯示2位, %Y年份顯示4位
date命令加減操作:
date +%Y%m%d #顯示當天年月日
date -d "+1 day" +%Y%m%d #顯示明天的日期
date -d "-1 day" +%Y%m%d #顯示昨天的日期
date -d "-1 month" +%Y%m%d #顯示上一月的日期
date -d "+1 month" +%Y%m%d #顯示下一月的日期
date -d "-1 year" +%Y%m%d #顯示前一年的日期
date -d "+1 year" +%Y%m%d #顯示下一年的日期
設定時間:
date -s 20180523 #設定成20120523,這樣會把具體時間設定成空00:00:00
date -s 01:01:01 #設定具體時間,不會對日期做更改
date -s "2018-05-23 01:01:01" #這樣可以設定全部時間
例1: 在命令中呼叫date命令輸出值
[[email protected] ~]# echo `date`
2018年 05月 25日 星期五 17:41:29 CST
[[email protected] ~]# echo $(date)
2018年 05月 25日 星期五 17:41:42 CST
[[email protected] ~]# echo `date +"%Y-%m-%d"`
2012-05-23
19.2.4 命令的巢狀使用,使用$( $( ))
[[email protected] ~]# find /root/ -name *.txt
[[email protected] ~]# VAR6=$(tar zcvf root.tar.gz $(find /root/ -name *.txt))
tar: 從成員名中刪除開頭的“/”
[[email protected] ~]# echo $VAR6 #檢視值, VAR6中儲存著tar的標準輸出
/root/.cache/tracker/db-version.txt /root/.cache/tracker/db-locale.txt /root/.cache/tracker/parser-sha1.txt /root/.cache/tracker/locale-for-miner-user-guides.txt /root/.cache/tracker/locale-for-miner-apps.txt /root/.cache/tracker/last-crawl.txt
。。。
實戰:分享一個系統時間錯誤,引起tar報警告
[[email protected] ~]# date -s "2012-03-03 21:25:00"
[[email protected] ~]# tar zxvf 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時間
[[email protected] ~]# ls /opt/root/.mozilla/firefox/wggimqlt.default/ -a #解壓成功
19.2.5 shell中單引號和雙引號區別
‘’ 在單引號中所有的字元包括特殊字元(KaTeX parse error: Expected 'EOF', got '\)' at position 7: ,'',`和\̲)̲都將解釋成字元本身而成為普通字…, ‘’, `和\以外所有的字元都解釋成字元本身,擁有“呼叫變數的值”、“引用命令”和“轉義符”的特殊含義 注:\轉義符,跟在\之後的特殊符號將失去特殊含義,變為普通字元。如$將輸出“$”符號,而不當做是變數引用 例:
[[email protected] ~]# echo $VAR1
123
[[email protected] ~]# echo \$VAR1
$VAR1
例1:給變數值賦於多個單詞,需要使用單引號和雙引號
[[email protected] ~]# VAR8='xuegdo mk'
[[email protected] ~]# echo $VAR8
xuegdo mk
例2:賦值時單引號和雙引號的區別
[[email protected] ~]# VAR8='xuegod mk $VAR1'
[[email protected] ~]# VAR9="xuegod mk $VAR1" #雙引中$符號有作用
[[email protected] ~]# echo $VAR8
xuegod mk $VAR1
[[email protected] ~]# echo $VAR9
xuegod mk 123
注:單引號之間的內容原封不動賦值給變數, 雙引號之間的內容如有特殊符號會保留它的特殊含義
刪除變數
[[email protected] ~]# unset VAR1
[[email protected] ~]# echo $VAR1
19.2.6 環境變數
在bash shell中,環境變數分為兩類:全域性變數和區域性變數
全域性變數:對於shell會話和所有的子shell都是可見的
區域性變數: 它只在自己的程序當中使用
例1:區域性變數
[[email protected] ~]# VAR1=123
[[email protected] ~]# echo $VAR1
123
[[email protected] ~]# vim a.sh
#!/bin/bash
echo $VAR1
[[email protected] ~]# echo $VAR1
123
[[email protected] ~]# bash a.sh #執行a.sh 時,會使用另一個bash去執行,就訪問不到$VAR1的值
例2:env命令檢視所全域性變數
[[email protected] ~]# env
[[email protected] ~]# env | grep PATH
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
例3:使用export把這個區域性變數輸出為全域性變數
[[email protected] ~]# export VAR1=xuegod
[[email protected] ~]# echo $VAR1
xuegod
[[email protected] ~]# vim a.sh #寫入以下內容
#!/bin/bash
echo $VAR1
[[email protected] ~]# bash a.sh #引用全域性變數成功
xuegod
互動: 雖然我們設定了export全域性變數,但是新開的xshell連線中,還是讀不到變數VAR1,怎麼辦?
例3:讓變數永久生效,可以把定義好的變數寫入配置檔案
當登入系統或新開啟一個ssh連線啟動bash程序時,一定會載入這4個配置檔案:
[[email protected] ~]# vim /etc/profile #系統全域性環境和登入系統的一些配置
[[email protected] ~]# vim /etc/bashrc #shell全域性自義配置檔案,用於自定義shell
[[email protected] ~]# vim /root/.bashrc #用於單獨自定義某個使用者的bash
[[email protected] ~]# vim /root/.bash_profile #使用者單獨自定義某個使用者的系統環境
互動:如何知道新建一個ssh連線,載入這4個配置檔案先後順序? 有思路:1,沒有思路:2 要會思考,思路很重要! 答:可以每個檔案的最後,追加一個echo命令,輸出一下檔案的名字
[[email protected] ~]# echo 'echo /etc/profile ' >> /etc/profile
[[email protected] ~]# echo 'echo /etc/bashrc' >> /etc/bashrc
[[email protected] ~]# echo 'echo /root/.bashrc ' >> /root/.bashrc
[[email protected] ~]# echo 'echo /root/.bash_profile ' >> /root/.bash_profile
[[email protected] ~]# ssh [email protected] #彈出以下資訊,就知道有優先順序了
/etc/profile
/etc/bashrc
/root/.bashrc
/root/.bash_profile
互動:知道載入的順序有什麼用?
可以在這裡新增木馬程式,只要管理登入系統,就觸發木馬程式! 現在大家知道學習作業系統原理的作用了吧。
[[email protected] ~]# echo 'touch /tmp/profile.txt ' >> /etc/profile
[[email protected] ~]# echo 'touch /tmp/bash_profile.txt ' >> /root/.bash_profile
下面開始插入永久變數:
[[email protected] ~]# vim /etc/profile #在檔案的最後插入
export VAR9=xuegod #=等號兩邊不能有空格
[[email protected] ~]# source /etc/profile #重新載入profile檔案
新開啟的連結中,也有了
19.2.7 設定PATH環境變數
SHELL要執行某一個程式,它要在系統中去搜索這個程式的路徑,path變數是用來定義命令和查詢命令的目錄,當我們安裝了第三方程式後,可以把第三方程式bin目錄新增到這個path路徑內,就可以在全域性呼叫這個第三方程式的
例1:
[[email protected] ~]# vim /opt/backup
#!/bin/bash
echo "Backup data is OK!"
[[email protected] ~]# chmod +x /opt/backup
[[email protected] ~]# /opt/backup
[[email protected] ~]# backup
bash: backup: 未找到命令...
將backup命令新增PATH中
[[email protected] ~]# PATH=/opt/:$PATH
[[email protected] ~]# backup #發現命令可以直接執行了,不用寫全路徑了
[[email protected] ~]# vim /etc/profile # 在檔案最後追加以下內容,永久生效
export PATH=/opt/:$PATH
[[email protected] ~]# source /etc/profile #重新載入配置檔案,使用配置生效
19.2.8 shell位置變數
Shell解釋執行使用者的命令時,將命令列的第一個字元作為命令名,而其它字元作為引數。
$0 獲取當前執行shell指令碼的檔案檔名,包括指令碼路徑,命令本身
$n 獲取當前指令碼的第n個引數 n=1,2.....n 當n大於9時 用${10}表示。
例子:
[[email protected] ~]# vim print.sh
#!/bin/bash
echo "本shell指令碼的檔名: $0"
echo "第1個引數: $1"
echo "第2個引數: $2"
echo "第3個引數: $3"
echo "第4個引數: $4"
[[email protected] ~]# chmod +x print.sh
[[email protected] ~]# ./print.sh 111 222 a.txt 444
本shell指令碼的檔名: ./print.sh
第1個引數: 111
第2個引數: 222
第3個引數: a.txt
第4個引數: 444
使用場景:伺服器啟動傳引數
[[email protected] ~]# /etc/init.d/network restart
19.2.9 特殊變數
有些變數是一開始執行Script指令碼時就會設定,且不能被修改,但我們不叫它只讀的系統變數,而叫它特殊變數。這些變數當一執行程式時就有了,以下是一些特殊變數:
$* 以一個單字串顯示所有向指令碼傳遞的引數;
如"$*"用【"】括起來的情況、以"$1 $2 … $n"的形式輸出所有引數
$# 傳遞到指令碼的引數個數
$$ 當前程序的程序號PID
$? 顯示最後命令的退出狀態;0表示沒有錯誤,其他任何值表明有錯誤
$! 後臺執行的最後一個程序的程序號pid
例子:
[[email protected] ~]# vim special_variable.sh #寫入以一下內容
#!/bin/bash
echo "$* 表示這個程式的所有引數 "
echo "$# 表示這個程式的引數個數"
echo "$$ 表示程式的程序ID "
touch /tmp/b.txt &
echo "$! 執行上一個後臺指令的PID"
echo "$$ 表示程式的程序ID "
echo "$? 表示上一個程式執行返回結果 "
[[email protected] ~]# bash special_variable.sh 11 22 33 44 55
11 22 33 44 55 表示這個程式的所有引數
11 22 33 44 55 表示這個程式的所有引數
5 表示這個程式的引數個數
45502 表程式的程序ID
45504 執行上一個後臺指令的PID
45502 表程式的程序ID
0 表示上一個程式執行返回結果
例2:常用的環境變數
[[email protected] opt]# cd /opt/
[[email protected] opt]# vim env.sh
#!/bin/bash
echo $HOME
echo $PATH
echo $PWD
[[email protected] opt]# bash env.sh
/root
/opt/:/opt/:/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin:/root/bin
/opt
Linux架構師高薪入口: 1.學神IT教育官方網站: http://xuegod.ke.qq.com 2.10年行業資深老鳥MK**:QQ2659153446** 3.加入Linux技術交流QQ群:722287089,即可獲得以下福利: ①定期分享免費學習資料與視訊(工具+筆記+拓展實戰) ②10年行業資深老鳥線上答疑:技能+實戰+專案分享+高薪就業 ③有機會免費領取Linux雲端計算叢集架構師4冊書籍
19.3 數學運算 19.3.1 expr命令
(1)對數字的基本計算,做比較時,輸出結果假為0,1為真;特殊符號用轉義符
[[email protected] ~]# expr 2 \> 5
0
[[email protected] ~]# expr 6 \> 5
1
[[email protected] ~]# expr 3 * 5
expr: 語法錯誤
[[email protected] ~]# expr 3 \* 5
15
[[email protected] ~]# expr 3 \+ 5
8
(2)對字串的處理
[[email protected] ~]# expr length "ni hao"
6
[[email protected] ~]# expr substr "ni hao" 2 4 #從第2個開始,擷取4個字元出來
i ha
19.3.2 使用$(( ))
**格式:”符號字首。 3、雙括號可以進行邏輯運算,四則運算 4、雙括號結構 擴充套件了for,while,if條件測試運算 5、支援多個表示式運算,各個表示式之間用“,”分開 常用的算數運算子
運算子 意義
++ -- 遞增及遞減,可前置也可以後置
+ - ! ~ 一元運算的正負號 邏輯與取反
+ - * / % 加減乘除與餘數
< <= > >= 比較大小符號
== != 相等 不相等
>> << 向左位移 向右位移
& ^ | 位的與 位的異或 位的或
&& || 邏輯與 邏輯或
? : 條件判斷
例1:
[[email protected] opt]# b=$((1+2))
[[email protected] opt]# echo $b
3
[[email protected] opt]# echo $((2*3))
6
例2:遞增和遞減
[[email protected] opt]# echo $((b++))
4
[[email protected] opt]# echo $((++b))
6
說明: a++或a--為先賦值再+1或減1 ; ++a或--a為先加1或減1,然後再進行賦值
例3:
求1到100的和
[[email protected] opt]# echo $((100*(1+100)/2))
5050
19.4 實戰-升級系統中的java版本到1.8版本-為後期安裝Hadoop叢集做準備 19.4.1 安裝jdk java執行環境
上傳jdk-8u161-linux-x64.rpm軟體包到xuegod63
[[email protected] ~]# rpm -ivh jdk-8u161-linux-x64.rpm
[[email protected] ~]#rpm -pql /root/jdk-8u161-linux-x64.rpm #通過檢視jdk的資訊可以知道jdk的安裝目錄在/usr/java
[[email protected] ~]#vim /etc/profile #在檔案的最後新增以下內容:
export JAVA_HOME=/usr/java/jdk1.8.0_161
export JAVA_BIN=/usr/java/jdk1.8.0_161/bin
export PATH=${JAVA_HOME}/bin:$PATH
export CLASSPATH=.:${JAVA_HOME}/lib/dt.jar:${JAVA_HOME}/lib/tools.jar
[[email protected] ~]#source /etc/profile #使配置檔案生效
驗證java執行環境是否安裝成功:
[[email protected] ~]# java -version
java version "1.8.0_161"
Java(TM) SE Runtime Environment (build 1.8.0_161-b12)
Java HotSpot(TM) 64-Bit Server VM (build 25.161-b12, mixed mode)
如果出現安裝的對應版本,說明java執行環境已經安裝成功。
注:這裡只是升級了jdk的版本,因為在我安裝的系統中已經安裝了jdk。
Linux架構師高薪入口: 1.學神IT教育官方網站: http://xuegod.ke.qq.com 2.10年行業資深老鳥MK:QQ2659153446 3.加入Linux技術交流QQ群:722287089,即可獲得以下福利: ①定期分享免費學習資料與視訊(工具+筆記+拓展實戰) ②10年行業資深老鳥線上答疑:技能+實戰+專案分享+高薪就業 ③有機會免費領取Linux雲端計算叢集架構師4冊書籍
微信公眾號: MK老師微訊號: 總結:
- 19.1 shell 基本語法
- 19.2 SHELL變數及運用
- 19.3 數學運算
- 19.4 實戰-升級系統中的java版本到1.8版本-為後期安裝Hadoop叢集做準備