01 . Linux自動化Shell詳細入門介紹及簡單應用
阿新 • • 發佈:2020-06-29
#### Shell簡介
> Shell 是一個 C 語言編寫的指令碼語言,它是使用者與 Linux 的橋樑,使用者輸入命令交給 Shell 解釋處理Shell 將相應的操作傳遞給核心(Kernel),核心把處理的結果輸出顯示到螢幕給使用者.
##### Shell分為兩類
`圖形介面 Shell(GUI Shell)`
> GUI為 Unix 或者類 Unix 作業系統構造一個功能完善、操作簡單以及介面友好的桌面環境。主流桌面環境有 KDE,Gnome 等。
`命令列介面 Shell(CLI Shell)`
> CLI是在使用者提示符下鍵入可執行指令的介面,使用者通過鍵盤輸入指令,完成一系列操作。
>
> 在 Linux 系統上主流的 CLI 實現是 Bash,是許多 Linux 發行版預設的 Shell。還有許多 Unix 上Shell,例如 tcsh、csh、ash、bsh、ksh 等。
##### 如何檢視系統支援的shell
> 一個系統中可以存在多個shell,可以通過cat /etc/shells命令檢視系統中安裝的shell,不同的shell可能支援的命令語法是不相同的,但是最常用的shell還是/bin/bash
```python
cat /etc/shells
/bin/sh
/bin/bash
/sbin/nologin
/usr/bin/sh
/usr/bin/bash
/usr/sbin/nologin
```
##### Shell命令基本格式
`shell命令可以分為兩大類`
* 一類是內建命令,即系統自帶的命令,如ls,這是顯示資料夾下檔案的命令;
* 另一類是外接命令,如vi,是呼叫vi編輯器的命令,而vi編輯器是一個軟體,這類命令由獨立的程式實現的命令,用於對linux的擴充套件,是外接命令
`shell命令格式如下`
```python
命令名 [選項] <引數1> <引數2>…
# 方括號內為可選的,命令可能有0個或者多個引數。
```
##### 系統變數
> 在命令列提示符直接執行 env、set 檢視系統或環境變數。env 顯示使用者環境變數,set 顯示 Shell預先定義好的變數以及使用者變數。可以通過 export 匯出成使用者變數。
`一些寫Shell指令碼時常用的系統變數`
```python
$SHELL 預設 Shell
$HOME 當前使用者家目錄
$IFS 內部欄位分隔符
$LANG 預設語言
$PATH 預設可執行程式路徑
$PWD 當前目錄
$UID 當前使用者 ID
$USER 當前使用者
$HISTSIZE 歷史命令大小,可通過 HISTTIMEFORMAT 變數設定命令執行時間
$RANDOM 隨機生成一個 0 至 32767 的整數
$HOSTNAME 主機名
```
##### 普通變數與臨時環境變數
> 普通變數定義:VAR=value
>
> 臨時環境變數定義:export VAR=value
>
> 變數引用:$VAR
>
> 下面看下他們之間區別:
>
> Shell 程序的環境變數作用域是 Shell 程序,當 export 匯入到系統變數時,則作用域是 Shell 程序及其 Shell 子程序。
>
> Shell 程序的環境變數作用域是 Shell 程序,當 export 匯入到系統變數時,則作用域是 Shell 程序及其 Shell 子程序。
>
> ps axjf 輸出的第一列是 PPID(父程序 ID),第二列是 PID(子程序 ID)當SSH 連線 Shell 時,當前終端 PPID(-bash)是 sshd 守護程式的 PID(root@pts/0),因此在當前終端下的所有程序的 PPID 都是-bash 的 PID,比如執行命令、執行指令碼。
>
> 所以當在-bash 下設定的變數,只在-bash 程序下有效,而-bash 下的子程序 bash 是無效的,當export 後才有效。
>
> 進一步說明:再重新連線 SSH,去除上面定義的變數測試下所以在當前 shell 定義的變數一定要 export,否則在寫指令碼時,會引用不到。
>
> 還需要注意的是退出終端後,所有使用者定義的變數都會清除。
>
> 在/etc/profile 下定義的變數就是這個原理.
##### 位置變數
> 位置變數指的是函式或指令碼後跟的第 n 個引數。
>
> 1−1−n,需要注意的是從第 10 個開始要用花括號呼叫,例如${10}
>
> shift 可對位置變數控制,例如:
```python
#!/bin/bash
echo "1: $1"
shift
echo "2: $2"
shift
echo "3: $3"
sh test.sh 1 2 3
1: 1
2: 3
3:
# 每執行一次 shift 命令,位置變數個數就會減一,而變數值則提前一位。shift n,可設定向前移動n位。
```
##### 特殊變數
```python
$0 # 指令碼自身名字
$? # 返回上一條命令是否執行成功,0 為執行成功,非 0 則為執行失敗
$# # 位置引數總數
$* # 所有的位置引數被看做一個字串
$@ # 每個位置引數被看做獨立的字串
$$ # 當前程序 PID
$! # 上一條執行後臺程序的 PID
```
##### 變數引用
| 賦值運算子 | 示例 |
| ---------- | ------------ |
| = | 變數賦值 |
| += | 兩個變數相加 |
##### 自定義變數與引用
```python
a=123
echo $a
123
a+=456
echo $a
123456
# Shell 中所有變數引用使用$符,後跟變數名
# 有時個別特殊字元會影響正常使用,就需要使用${a},例如
[root@redis ~]# b=123
[root@redis ~]# echo $b
123
[root@redis ~]# echo ${b}
123
# 有時個別特殊字元會影響正常引用,那麼需要使用${VAR}
[root@redis ~]# echo $b123
[root@redis ~]# echo ${b}123
123123
# 將命令結果作為變數值
[root@redis ~]# c=`echo 123`
[root@redis ~]# echo $c
123
[root@redis ~]# c=$(echo 123)
[root@redis ~]# echo $c
123
# 這裡的反撇號等效於$(),都是用於執行 Shell 命令。
# 單引號和雙引號
[root@redis ~]# d=1
[root@redis ~]# d="1 2 $d"
[root@redis ~]# echo $d
1 2 1
[root@redis ~]# c=1
[root@redis ~]# c='1 2 $c'
[root@redis ~]# echo $c
1 2 $c
# 單引號是告訴 Shell 忽略特殊字元,而雙引號則解釋特殊符號原有的意義,比如$ 、 !。
```
##### shell命令小知識
`1.shell自動補齊和歷史記錄`
> shell會在使用者輸入命令前幾個字母后按 鍵自動補齊,如果有多個候選命令會顯示出全部命令。
> shell會自動記錄使用者使用的命令,使用者可以按 上 下 鍵 來檢視。
`2.shell提示符`
> shell提示符有兩種,一種是 **$**結尾,為普通使用者許可權下的提示符號,一種是**#**結尾,為管理員許可權,使用者可以用su命令切換使用者,如下圖:
`3.輸入輸出重定向`
> shell命令是控制檯命令,使用標準輸入和輸出裝置,即從鍵盤接受輸入,將結果顯示在顯示器上。重定向可以將shell的輸入輸出重定向到檔案或裝置。
> 輸入重定向符號為”<”,輸出重定向符號為”>”和”>>”。如果shell命令 “X”在執行過程中,需要從控制檯獲得資料,那麼執行”X < file”可以從file檔案中獲得所需資料。如果X在執行過程中產生資料,可以用 “X > file”和”X >> file”將結果輸入到檔案。”>”為覆蓋輸入,”>>”為追加輸入
`4.管道`
> linux系統中,管道是一種先進先出的單資料通道,利用管道符號”|”可以將多個命令組合到一起,把一個命令的輸出傳遞給下一個命令作為輸入,最終得到經過多個命令一次處理的結果。如,用ll和grep結合來查詢當前目錄是否有這個檔案:
##### 什麼是Shell指令碼
> 指令碼就是shell命令組成的檔案,這些命令都是可執行程式的名字,指令碼不用編譯即可通過直譯器解釋執行。
> 它是一種解釋型語言,我們可以用shell指令碼操存執行動作,用指令碼判定命令的執行條件,用指令碼來實現動作的批量執行
#### Shell簡單使用
##### 指令碼開頭
> 為了便於指令碼的使用者可以快捷的瞭解到指令碼的用途與其使用的直譯器,通常我們需要在指令碼的開頭加上註釋。
```python
#!/bin/bash 指令碼使用的直譯器,通常用幻數“#!”指定
# Autho: 指令碼作者
# Create_date 指令碼創作時間
# Mail: 指令碼作者聯絡方式
# Description: 指令碼作用解釋
# Version: 指令碼的版本
```
##### 指令碼內容
> 在shell指令碼中可以出現任何系統命令,輸入你想要執行的命令即可,我們建立一個hello.sh
```python
cat hello.sh
#!/bin/bash 指令碼使用的直譯器,通常用幻數“#!”指定
# Autho: 指令碼作者
# Create_date 指令碼創作時間
# Mail: 指令碼作者聯絡方式
# Description: 指令碼作用解釋
# Version: 指令碼的版本
echo hello
```
##### shell指令碼的執行方法
`首先我們給指令碼執行許可權`
```python
chmod +x 指令碼路徑/指令碼名
```
`執行方式1: 輸入指令碼的絕對路徑或者相對路徑`
```python
# 注意: 如果不給+x許可權是不能這種方式執行指令碼的
# 絕對路徑
/root/test.sh
hello
# 相對路徑
./test.sh
hello
```
`執行方式2: sh +指令碼`
```python
sh /root/test.sh
hello
```
`執行方式3: source + 指令碼`
```python
source /root/test.sh
hello
```
`執行方式4: . + 指令碼`
```python
. test.sh
hello
```
`區別`
```python
# 第一種和第二種會新開啟一個bash,不同bash中的變數無法共享,
# 第三種和第四種是直接使用當前執行環境作為直譯器執行環