Shell編程(一)- shell腳本介紹,date命令,shell變量,字符串處理,顏色

[toc]html

shell編程

1、shell 腳本介紹

Shell 是一個用 C 語言編寫的程序,它是用戶使用 Linux 的橋樑。Shell 既是一種命令語言,又是一種程序設計語言。 shell是一種腳本語言; 可使用邏輯判斷、循環等語法; 可自定義函數; shell是系統命令的集合; shell腳本能夠實現自動化運維,能大大增長咱們的運維效率;shell

說明了shell 腳本在工做的重要性,shell腳本就是一些命令的集合,是自動化運維的重要部分編程

2、 Shell腳本結構和執行

下面跟着步驟來一步步學習如何寫shell腳本數組

2.1 建立shell腳本實驗環境

[root@localhost ~]# mkdir shell
[root@localhost ~]# cd shell/
[root@localhost shell]# ls
[root@localhost shell]# vi 01.sh

shell腳本一般都是.sh爲後綴名,但不是說不加.sh的腳本就不能執行,只是你們的一個習慣而已,因此若是發新了以.sh爲後綴的文件,那麼它可能就是一個shell腳本.bash

mark

本例中,腳本文件01.sh,進入編輯狀態後,第一行要以#!/bin/bash開頭,表示該文件使用的是bash語法.而/bin/bash是Bash的解釋器命令路徑.運維

2.2 執行該腳本 #sh.01.sh

[root@localhost shell]# sh 01.sh
123
 22:43:14 up 25 min,  1 user,  load average: 0.00, 0.01, 0.01
USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
root     pts/0    192.168.72.1     22:26    2.00s  0.08s  0.00s w
01.sh

把#!/bin/bash這一行刪除,運行命令後也能執行但這樣不符合規範.ssh

mark

2.3 另外一種方法執行該腳本 #./01.sh

使用該方法運行shell腳本的前提是腳本自己有執行權限,須要給腳本加x權限函數

[root@localhost shell]# chmod +x 01.sh
[root@localhost shell]# ./01.sh
123
 23:18:34 up  1:01,  1 user,  load average: 0.00, 0.01, 0.03
USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
root     pts/0    192.168.72.1     22:26    2.00s  0.11s  0.01s w
01.sh

2.4 查看解釋路徑/bin/bash和/bin/sh

mark

[root@localhost shell]#  bash 01.sh
123
 23:37:15 up  1:19,  1 user,  load average: 0.00, 0.01, 0.03
USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
root     pts/0    192.168.72.1     22:26    3.00s  0.20s  0.01s w
01.sh

這裏是否能夠理解有三種方法均可以執行shell腳本,可是本機驗證成功,不表明其餘機器虛擬機是否成功,後續測試post

2.5 舉例腳本的編輯方式,註釋等

[root@localhost shell]# vi /etc/init.d/network

#! /bin/bash
#
# network       Bring up/down networking
#
# chkconfig: 2345 10 90
# description: Activates/Deactivates all network interfaces configured to \
#              start at boot time.
#

mark

2.6 sh -x 查看shell腳本執行過程,方便後續調試

[root@localhost shell]# sh -x 01.sh
+ echo 123
123
+ w
 23:40:21 up  1:22,  1 user,  load average: 0.00, 0.01, 0.03
USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
root     pts/0    192.168.72.1     22:26    5.00s  0.22s  0.01s w
+ ls
01.sh
[root@localhost shell]# bash -x 01.sh
+ echo 123
123
+ w
 23:40:29 up  1:23,  1 user,  load average: 0.00, 0.01, 0.03
USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
root     pts/0    192.168.72.1     22:26    5.00s  0.21s  0.00s w
+ ls
01.sh

2.7 sh -n 檢測shell腳本是否有語法錯誤

mark

3、date命令用法

date命令用於顯示或設置系統時間與日期。 命令選項:學習

[root@xavi ~]# date  //當前日期
2018年 04月 17日 星期二 22:06:22 CST
[root@xavi ~]# cal  //當前日曆
      四月 2018     
日 一 二 三 四 五 六
 1  2  3  4  5  6  7
 8  9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30

[root@xavi ~]# date +%Y  //年
2018
[root@xavi ~]# date +%y  //年縮寫
18

[root@xavi ~]# date +%m  //月
04

[root@xavi ~]# date +%Y%m%d //年月日
20180417

[root@xavi ~]# date +%F
2018-04-17

[root@xavi ~]# date +%H  //小時
22
[root@xavi ~]# date +%M   //分鐘
23
[root@xavi ~]# date +%S   //秒
10

[root@xavi ~]# date +%s  //時間戳,時間戳是從1970年1月1日(UTC/GMT的午夜)開始所通過的秒數,不考慮閏秒
1523975099

[root@xavi ~]# date +%T //時間的完整顯示
22:27:04

[root@xavi ~]# date "+%Y-%m-%d %H:%M:%S %w" // 年月日,時分秒,星期  
2018-04-17 22:20:50 2

[root@xavi ~]# date -d "-1 day"
2018年 04月 16日 星期一 22:31:20 CST
[root@xavi ~]# date -d "-1 day" +%F
2018-04-16

[root@xavi ~]# date -d "-1 month" +%F
2018-03-17
[root@xavi ~]# date -d "-1 year" +%F
2017-04-17
[root@xavi ~]# date -d "-1 hour" +%T
21:44:30

[root@xavi ~]# date +%s -d "2018-04-17 22:46"  //  日期轉化爲時間戳
1523976360

4、shell腳本中的變量

當腳本中使用某個字符串較頻繁而且字符串長度很長時就應該使用變量代替
 使用條件語句時,常使用變量    if [ $a -gt 1 ]; then ... ; fi
 引用某個命令的結果時,用變量替代   n=`wc -l 1.txt`
 寫和用戶交互的腳本時,變量也是必不可少的  read -p "Input a number: " n; echo $n   若是沒寫這個n,能夠直接使用$REPLY
 內置變量 $0, $1, $2…    $0表示腳本自己,$1 第一個參數,$2 第二個 ....       $#表示參數個數
 數學運算a=1;b=2; c=$(($a+$b))或者$[$a+$b]

4.1 shell變量

4.1 系統變量

在命令行提示符直接執行env、set查看系統或環境變量。env顯示用戶環境變量,set顯示Shell預先定義好的變量以及用戶變量。能夠經過export導出成用戶變量。 一些寫Shell腳本時經常使用的系統變量:

mark

4.2 普通變量與臨時環境變量

普通變量定義:VAR=value 臨時環境變量定義:export VAR=value 變量引用:$VAR

下面看下他們之間區別:

Shell進程的環境變量做用域是Shell進程,當export導入到系統變量時,則做用域是Shell進程及其Shell子進程。

[root@xaviyunserver sbin]# ps axjf |grep pts
 1229  1773  1773  1773 ?           -1 Ss       0   0:00  \_ sshd: root@pts/0
 1773  1775  1775  1775 pts/0     2631 Ss       0   0:00      \_ -bash
 1775  1825  1825  1775 pts/0     2631 T        0   0:00          \_ sh test2.sh
 1775  2631  2631  1775 pts/0     2631 R+       0   0:00          \_ ps axjf
 1775  2632  2631  1775 pts/0     2631 S+       0   0:00          \_ grep --color=auto pts
[root@xaviyunserver sbin]# echo $$
1775
[root@xaviyunserver sbin]# VAR=123
[root@xaviyunserver sbin]# echo $VAR
123
[root@xaviyunserver sbin]# bash
[root@xaviyunserver sbin]# echo $$
2633
[root@xaviyunserver sbin]# ps axjf |grep pts
 1229  1773  1773  1773 ?           -1 Ss       0   0:00  \_ sshd: root@pts/0
 1773  1775  1775  1775 pts/0     2649 Ss       0   0:00      \_ -bash
 1775  1825  1825  1775 pts/0     2649 T        0   0:00          \_ sh test2.sh
 1775  2633  2633  1775 pts/0     2649 S        0   0:00          \_ bash
 2633  2649  2649  1775 pts/0     2649 R+       0   0:00              \_ ps axjf
 2633  2650  2649  1775 pts/0     2649 S+       0   0:00              \_ grep --color=auto pts
[root@xaviyunserver sbin]# echo $VAR

[root@xaviyunserver sbin]# exit
exit
[root@xaviyunserver sbin]# echo $VAR
123

[root@xaviyunserver sbin]# ps -ef |grep ssh
root      1229     1  0 07:58 ?        00:00:00 /usr/sbin/sshd -D

ps axjf輸出的第一列是PPID(父進程ID),第二列是PID(子進程ID) 當SSH鏈接Shell時,當前終端PPID(-bash)是sshd守護程序的PID(root@pts/0),所以在當前終端下的全部進程的PPID都是-bash的PID,好比執行命令、運行腳本。 因此當在-bash下設置的變量,只在-bash進程下有效,而-bash下的子進程bash是無效的,當export後纔有效。

  • [ ] 進一步說明:再從新鏈接SSH,去除上面定義的變量測試下
[root@xaviyunserver sbin]# sh test.sh
 1229  1773  1773  1773 ?           -1 Ss       0   0:00  \_ sshd: root@pts/0
 1773  1775  1775  1775 pts/0     2693 Ss       0   0:00      \_ -bash
 1775  1825  1825  1775 pts/0     2693 T        0   0:00          \_ sh test2.sh
 1775  2693  2693  1775 pts/0     2693 S+       0   0:00          \_ sh test.sh
 2693  2694  2693  1775 pts/0     2693 R+       0   0:00              \_ ps -axjf
 2693  2695  2693  1775 pts/0     2693 R+       0   0:00              \_ sh test.sh
2693
[root@xaviyunserver sbin]# cat test.sh
#!/bin/bash
ps -axjf |grep pts
echo $$
echo $VAR

[root@xaviyunserver sbin]# sh test.sh
 1229  1773  1773  1773 ?           -1 Ss       0   0:00  \_ sshd: root@pts/0
 1773  1775  1775  1775 pts/0     2693 Ss       0   0:00      \_ -bash
 1775  1825  1825  1775 pts/0     2693 T        0   0:00          \_ sh test2.sh
 1775  2693  2693  1775 pts/0     2693 S+       0   0:00          \_ sh test.sh
 2693  2694  2693  1775 pts/0     2693 R+       0   0:00              \_ ps -axjf
 2693  2695  2693  1775 pts/0     2693 R+       0   0:00              \_ sh test.sh
2693

[root@xaviyunserver sbin]# export VAR
[root@xaviyunserver sbin]# sh test.sh
 1229  1773  1773  1773 ?           -1 Ss       0   0:00  \_ sshd: root@pts/0
 1773  1775  1775  1775 pts/0     2696 Ss       0   0:00      \_ -bash
 1775  1825  1825  1775 pts/0     2696 T        0   0:00          \_ sh test2.sh
 1775  2696  2696  1775 pts/0     2696 S+       0   0:00          \_ sh test.sh
 2696  2697  2696  1775 pts/0     2696 R+       0   0:00              \_ ps -axjf
 2696  2698  2696  1775 pts/0     2696 R+       0   0:00              \_ sh test.sh
2696
123
  • [ ] 因此在當前shell定義的變量必定要export,不然在寫腳本時,會引用不到。 還須要注意的是退出終端後,全部用戶定義的變量都會清除。

在/etc/profile下定義的變量就是這個原理,後面有章節會講解Linux經常使用變量文件。

4.3 位置變量,位置變量指的是函數或腳本後跟的第n個參數。

$1-$n,須要注意的是從第10個開始要用花括號調用,例如${10}

shift可對位置變量控制,例如:

#!/bin/bash
echo "1: $1"
shift
echo "2: $2"
shift
echo "3: $3"
shift

[root@xaviyunserver sbin]# sh postion.sh
1: 
2: 
3: 
[root@xaviyunserver sbin]# sh postion.sh a b c
1: a
2: c
3:
  • [ ] 每執行一次shift命令,位置變量個數就會減一,而變量值則提早一位。shift n,可設置向前移動n位。

4.4 特殊變量

mark

4.5 變量引用

4.5.1 自定義變量與引用

Shell中全部變量引用使用$符,後跟變量名。 有時個別特殊字符會影響正常引用,那麼須要使用${VAR},例如:

# VAR=123
# echo $VAR
123
# echo $VAR_   # Shell容許VAR_爲變量名,因此此引用認爲這是一個有效的變量名,故此返回空
 
# echo ${VAR}
123

4.5.2 還有時候變量名與其餘字符串緊礙着,也會誤認爲是整個變量:

# echo $VAR456
 
# echo ${VAR}456
123456

4.5.3 將命令結果做爲變量值

# VAR=`echo 123` 
# echo $VAR
123
# VAR=$(echo 123)
# echo $VAR
123
這裏的反撇號等效於$(),都是用於執行Shell命令。

4.6 雙引號和單引號

在變量賦值時,若是值有空格,Shell會把空格後面的字符串解釋爲命令:

# VAR=1 2 3
-bash: 2: command not found
# VAR="1 2 3"
# echo $VAR
1 2 3
# VAR='1 2 3'
# echo $VAR 
1 2 3

看不出什麼區別,再舉個說明:

# N=3
# VAR="1 2 $N"
# echo $VAR
1 2 3
# VAR='1 2 $N'
# echo $VAR
1 2 $N

單引號是告訴Shell忽略特殊字符,而雙引號則解釋特殊符號原有的意義,好比$、!。

4.7 註釋

Shell註釋也很簡單,只要在每行前面加個#號,即表示Shell忽略解釋。

5、Shell字符串處理之${}及顏色

用${}引用變量,${}還有一個重要的功能,就是文本處理,單行文本基本上能夠知足你全部需求。

5.1 獲取字符串長度

# VAR='hello world!'
# echo $VAR
hello world!
# echo ${#VAR}
12

5.2 字符串切片

格式:

${parameter:offset}
${parameter:offset:length}

截取從offset個字符開始,向後length個字符。

截取hello字符串:
# VAR='hello world!'
# echo ${VAR:0:5}
hello
截取wo字符:
# echo ${VAR:6:2}
wo
截取world!字符串:
# echo ${VAR:5}
world!
截取最後一個字符:
# echo ${VAR:(-1)}
!
截取最後二個字符:
# echo ${VAR:(-2)}
d!
截取從倒數第3個字符後的2個字符:
# echo ${VAR:(-3):2}
ld

5.3 替換字符串

格式:${parameter/pattern/string}

# VAR='hello world world!'
將第一個world字符串替換爲WORLD:
# echo ${VAR/world/WORLD}
hello WORLD world!
將所有world字符串替換爲WORLD:
# echo ${VAR//world/WORLD}
hello WORLD WORLD!

5.4 字符串截取

格式:

${parameter#word}   # 刪除匹配前綴
${parameter##word}  
${parameter%word}   # 刪除匹配後綴
${parameter%%word}
  • [ ] # 去掉左邊,最短匹配模式,##最長匹配模式。
  • [ ] % 去掉右邊,最短匹配模式,%%最長匹配模式。
# URL="http://www.baidu.com/baike/user.html"

以//爲分隔符截取右邊字符串:
# echo ${URL#*//}         
www.baidu.com/baike/user.html

以/爲分隔符截取右邊字符串:
# echo ${URL##*/}
user.html

以//爲分隔符截取左邊字符串:
# echo ${URL%%//*}     
http:

以/爲分隔符截取左邊字符串:
# echo ${URL%/*}
http://www.baidu.com/baike

以.爲分隔符截取左邊:
# echo ${URL%.*}
http://www.baidu.com/baike/user

以.爲分隔符截取右邊:
# echo ${URL##*.}
html
  • [ ] # 去掉左邊,從左邊匹配第一個,##從右邊匹配第一個。
  • [ ] % 去掉右邊,從右邊匹配第一個,%%從左邊匹配第一個。 有*號狀況下才這樣。

5.5 變量狀態賦值

${VAR:-string}  若是VAR變量爲空則返回string
${VAR:+string}  若是VAR變量不爲空則返回string
${VAR:=string}  若是VAR變量爲空則從新賦值VAR變量值爲string
${VAR:?string}  若是VAR變量爲空則將string輸出到stderr

若是變量爲空就返回hello world!:

# VAR=
# echo ${VAR:-'hello world!'}

hello world! 若是變量不爲空就返回hello world!:

# VAR="hello"
# echo ${VAR:+'hello world!'}

hello world! 若是變量爲空就從新賦值:

# VAR=
# echo ${VAR:=hello}
hello
# echo $VAR
hello

若是變量爲空就將信息輸出stderr:

# VAR=
# echo ${VAR:?value is null}   
-bash: VAR: value is null

${}主要用途大概就這麼多了,另外還能夠獲取數組元素。

5.6 字符串顏色

再介紹下字符串輸出顏色,有時候關鍵地方須要醒目,顏色是最好的方式:

mark

格式:

  • [ ] \033[1;31;40m # 1是顯示方式,可選。31是字體顏色。40m是字體背景顏色。

  • [ ] \033[0m # 恢復終端默認顏色,即取消顏色設置。

#!/bin/bash

# 字體顏色,顯示方式默認爲空
for i in {31..37}; do
    echo -e "\033[$i;40mHello world!\033[0m"
done

# 背景顏色,顯示方式默認爲空
for i in {41..47}; do
    echo -e "\033[47;${i}mHello world!\033[0m"
done

# 顯示方式
for i in {1..8}; do
    echo -e "\033[$i;31;40mHello world!\033[0m"
done
相關文章
相關標籤/搜索