1. 程式人生 > >Centos7.5-shell指令碼的基礎

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 使用$(( ))

**格式:121ca++,ba++a=a+12((表示式1,表達2))** 特點: 1、在雙括號結構中,所有表示式可以像c語言一樣,如:a++,b--等。a++ 等價於 a=a+1 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叢集做準備