shell腳本基礎用法

shell腳本
確切一點說,Shell就是一個命令行解釋器,它的作用就是遵循一定的語法將輸入的命令加以解釋並傳給系統。它爲用戶提供了一個向Linux發送請求以便運行程序的接口系統級程序,用戶可以用Shell來啓動、掛起、停止甚至是編寫一些程序。 Shell本身是一個用C語言編寫的程序,它是用戶使用Linux的橋樑。Shell既是一種命令語言,又是一種程序設計語言,作爲命令語言,它互動式地解釋和執行用戶輸入的命令;作爲程序設計語言,它定義了各種變量和參數,並提供了許多在高階語言中才具有的控制結構,包括循環和分支。它雖然不是 Linux系統內核的一部分,但它調用了系統內核的大部分功能來執行程序、創建文檔並以並行的方式協調各個程序的運行。

shell腳本的優勢在於處理操作系統底層的業務 (linux系統內部的應用都是shell腳本完成)因爲有大量的linux系統命令爲它做支撐。2000多個命令都是shell腳本編程的有力支撐,特別是grep、awk、sed等。例如:一鍵軟件安裝、優化、監控報警腳本,常規的業務應用,shell開發更簡單快速,符合運維的簡單、易用、高效原則。

shell腳本
打開文本編輯器(可以使用vi/vim命令來創建文件),新建一個文件test.sh,擴展名爲sh

輸入一些代碼,第一行一般是這樣:

[root@zhaocheng ~]# cat test.sh 
#!/bin/bash
echo "Hello World"

[root@zhaocheng ~]# bash test.sh 
Hello World

"#!" 是一個約定的標記,它告訴系統這個腳本需要什麼解釋器來執行,即使用哪一種Shell。
echo命令用於向窗口輸出文本

查看系統中的解釋器

[root@localhost ~]# cat /etc/shells 
/bin/sh
/bin/bash
/usr/bin/sh
/usr/bin/bash
/bin/tcsh
/bin/csh

輸入echo $SHELL默認系統顯示/bin/bash

[root@localhost ~]# echo $SHELL
/bin/bash

輸入bash -version顯示shell版本

[root@localhost ~]# bash -version
GNU bash, version 4.2.46(2)-release (x86_64-redhat-linux-gnu)
Copyright (C) 2011 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>

This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

腳本書寫規範
建議統一存放目錄,方便運維的管理查找去執行
[root@localhost ~]# mkdir /shell/scripts -pv
腳本以.sh爲擴展名
開頭指定腳本解釋器。
開頭加版本版權等信息,可配置~/.vimrc文件自動添加。
腳本不要用中文註釋,儘量用英文註釋。

代碼書寫優秀習慣
成對的內容一次性寫出來,防止遺漏,如[ ]、' '、" "等
[ ]兩端要有空格,先輸入[ ],退格,輸入2個空格,再退格寫。
流程控制語句一次書寫完,再添加內容。(if 條件 ; then 內容;fi)ddd
通過縮進讓代碼易讀。
腳本中的引號都是英文狀態下的引號,其他字符也是英文狀態。

shell腳本的執行

[root@localhost scripts]# chmod +x test.sh 
[root@localhost scripts]# ls
test.sh
[root@localhost scripts]# ./test.sh 
Hello World
[root@localhost scripts]# source test.sh 
Hello World
[root@localhost scripts]# bash test.sh 
Hello World
[root@localhost scripts]# sh test.sh 
Hello World

**shell的變量
變量可以分爲兩類:環境變量(全局變量)和普通變量(局部變量)

  環境變量也可稱爲全局變量,可以在創建他們的Shell及其派生出來的任意子進程shell中使用,環境變量又可分爲自定義環境變量和Bash內置的環境變量

  普通變量也可稱爲局部變量,只能在創建他們的Shell函數或Shell腳本中使用。普通變量一般是由開發者用戶開發腳本程序時創建的。

環境變量
可以通過env,或者export獲取到系統中的環境變量**

[root@localhost scripts]# env
XDG_SESSION_ID=141785
HOSTNAME=zhaocheng
SHELL=/bin/bash
TERM=xterm
HISTSIZE=3000

輸出系統中的變量

[root@localhost scripts]# echo $HOME
/root
[root@localhost scripts]# echo $USER
root
[root@localhost scripts]# echo $HISTSIZE
3000
[root@localhost scripts]# echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/date/soft/logstash-7.5.0/bin:/root/bin

普通變量
一般在本地設置並執行的,但是在一個腳本中去執行就是無效的

[root@localhost scripts]# xiaoming=26
[root@localhost scripts]# echo $xiaoming
26
[root@localhost scripts]# cat test.sh 
#!/bin/bash
echo $xiaoming

[root@localhost scripts]# bash test.sh 

這樣去執行是無法獲取到普通的變量的,因爲這是本地的變量值,如果將它加入到系統變量中當然這就獲取到了
而剛纔通過export命令查看到$PATH就是系統變量的,當然這樣的,我們執行就能在我們腳本中直接去調用這個變量

[root@localhost scripts]# cat test.sh 
#!/bin/bash
echo $PATH
[root@localhost scripts]# bash test.sh 
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/date/soft/logstash-7.5.0/bin:/root/bin

現在我們將我們平時定義的變量加入到shell中,一般開發一些腳本的時候方便管理也都會直接將變量在我們全局變量中去調用,提升腳本效率與清晰,變量爲大寫,這種也是不建議去使用的,退出時,變量就失效,建議寫到腳本中
查看我們的系統加入的變量可以使用export去查看

[root@localhost scripts]# export XIAOMING=26
[root@localhost scripts]# cat test.sh 
#!/bin/bash
echo $XIAOMING
[root@localhost scripts]# bash test.sh 
26

簡單示例
定義變量將變量導入到系統變量中

[root@localhost scripts]# export TENGXUN=mahuateng
[root@localhost scripts]# export ALI=mayun
[root@localhost scripts]# export BAIDU=liyanhong

[root@localhost scripts]# cat test.sh 
#!/bin/bash
echo $TENGXUN
echo $BAIDU
echo $ALI

執行效果是直接調用我們的系統變量,而不需要腳本中再去寫上面的語法,不過都可以使用,根據自己的習慣

[root@localhost scripts]# bash test.sh 
mahuateng
liyanhong
mayun

另外就是這裏如果沒有寫進系統變量也能去調用到,可以使用source,這樣也能獲取到

[root@localhost scripts]# LIHONGLEI=lei
[root@localhost scripts]# cat test.sh 
#!/bin/bash
echo $LIHONGLEI
[root@localhost scripts]# source test.sh 
lei

也可以將這個加入到/etc/profile中也可以執行

[root@localhost scripts]# cat test.sh 
#!/bin/bash
echo $PING
[root@localhost scripts]# tail -1 /etc/profile
PING=guo

這個需要source /etc/profile一下才能獲取到

[root@localhost scripts]# source /etc/profile
[root@localhost scripts]# source test.sh 
guo

一般當linux系統啓動的時候,系統將啓動一個用戶shell,這個shell直接就可以使用shell命令或者聲明變量,比如,定義聲明變量,但這個在腳本中輸出爲空,在局部變量需要添加$才能引用

[root@localhost scripts]# name=lili
[root@localhost scripts]# echo name
name
[root@localhost scripts]# echo $name
lili

**爲什麼要用export命令?
其實主要是我們定義一個變量時可以在子shell中被調用,而不需要重複去定義,但是當shell執行結束就會自動退出,該環境變量無法繼續使用

變量在引號的使用
一般是特殊字符的時候需要使用'',如果是引用系統變量的話,必須使用""**

[root@tengxunyun ~]# name1=pingguo
[root@tengxunyun ~]# name2='li'
[root@tengxunyun ~]# name3="juzi"
[root@tengxunyun ~]# name4='^^^^'
[root@tengxunyun ~]# name5='&&& &&& $SHELL'
[root@tengxunyun ~]# name6="kkk #### $SHELL"

[root@tengxunyun ~]# echo $name1
pingguo
[root@tengxunyun ~]# echo $name2
li
[root@tengxunyun ~]# echo $name3
juzi
[root@tengxunyun ~]# echo $name4
^^^^
[root@tengxunyun ~]# echo $name5
&&& &&& $SHELL
[root@tengxunyun ~]# echo $name6
kkk #### /bin/bash

變量使用反引號賦值
如果是變量的話,一定要加$不然它以爲是普通文件,帶_劃線的變量需要將前面變量{}起來

[root@tengxunyun ~]# time=`date`
[root@tengxunyun ~]# echo time
time
[root@tengxunyun ~]# echo $time
Thu Feb 20 13:34:26 CST 2020

[root@tengxunyun ~]# file=`ll`
[root@tengxunyun ~]# echo $file
total 4 -rw-r--r-- 1 root root 26 Feb 20 12:07 test.sh

[root@tengxunyun ~]# echo ${time}_day
Thu Feb 20 13:34:26 CST 2020_day
[root@tengxunyun ~]# echo $time-day
Thu Feb 20 13:34:26 CST 2020-day

**編寫腳本的時候我們需要將註釋加到腳本的開頭,這樣的話,可以增加我們的腳本的規範

使用vimrc文件**

[root@zhaocheng ~]# cat .vimrc 
autocmd BufNewFile *.py,*.cc,*.sh,*.java exec ":call SetTitle()"

func SetTitle()
    if expand("%:e") == 'sh'
        call setline(1,"#!/bin/bash")
        call setline(2, "##############################################################")
        call setline(3, "# File Name: ".expand("%"))
        call setline(4, "# Version: V1.0")
        call setline(5, "# Author: clsn")
        call setline(6, "# Organization: http://blog.znix.top")
        call setline(7, "# Created Time : ".strftime("%F %T"))
        call setline(8, "# Description:")
        call setline(9, "##############################################################")
        call setline(10, "")
    endif
endfunc

位置變量
shell腳本基礎用法

$0獲取當前的shell腳本的文件名,$1也就是獲取的第二個參數,$2是獲取的第二個參數,${11}當參數超過9以上就需要使用{}引起來

[root@zhaocheng ~]# cat test.sh 
#!/bin/bash
echo $0
echo "第一個參數:"$1
echo "第二個參數:"$2
echo "第11個參數:"${11}

[root@zhaocheng ~]# bash test.sh 1 3 3 5 6 78  8 89  9  654 77
test.sh
第一個參數:1
第二個參數:3
第11個參數:77

$#相當於列出總共多少個參數

[root@zhaocheng ~]# cat test.sh 
#!/bin/bash
echo $0
echo "第一個參數:"$1
echo "第二個參數:"$2
echo "第11個參數:"${11}
echo "列出有多少個參數:"$#

[root@zhaocheng ~]# bash test.sh 66 99 00 9990
test.sh
第一個參數:66
第二個參數:99
第11個參數:
列出有多少個參數:4

*$相當於列出所有的參數**

[root@zhaocheng ~]# cat test.sh 
#!/bin/bash

echo $0
echo "第一個參數:"$1
echo "第二個參數:"$2
echo "第11個參數:"${11}
echo "列出有多少個參數:"$#
echo "列出所有輸出的參數:"$*

[root@zhaocheng ~]# bash test.sh 99 00 88 77 66 55 44 33
test.sh
第一個參數:99
第二個參數:00
第11個參數:
列出有多少個參數:8
列出所有輸出的參數:99 00 88 77 66 55 44 33

*$和¥@對比**

[root@zhaocheng ~]# set -- "It's" a nice day today
[root@zhaocheng ~]# echo $1
It's
[root@zhaocheng ~]# echo $2
a
[root@zhaocheng ~]# echo $3
nice
[root@zhaocheng ~]# echo $4
day
[root@zhaocheng ~]# echo $5
today

[root@zhaocheng ~]# for i in $1;do echo $i;done
It's
[root@zhaocheng ~]# for i in $2;do echo $i;done
a
[root@zhaocheng ~]# for i in $*;do echo $i;done
It's
a
nice
day
today
[root@zhaocheng ~]# for i in $#;do echo $i;done
5
[root@zhaocheng ~]# for i in $@;do echo $i;done
It's
a
nice
day
today
[root@zhaocheng ~]# for i in "$@";do echo $i;done
It's
a
nice
day
today

進程狀態變量
shell進程特殊狀態變量

shell腳本基礎用法

**定義變量方式
1、直接賦值
2、傳遞參數
3、交互式設置變量,使用read命令

read在命令行的使用**

[root@zhaocheng ~]# read
999
[root@zhaocheng ~]# echo $REPLY
999
[root@zhaocheng ~]# read kele

[root@zhaocheng ~]# read kele
niunai
[root@zhaocheng ~]# echo $kele
niunai
[root@zhaocheng ~]# echo $REPLY
999

在腳本中的使用

[root@zhaocheng ~]# cat echo.sh 
#!/bin/bash
read -p "請輸入:" i
echo $i
[root@zhaocheng ~]# bash echo.sh 
請輸入:chengzhi
chengzhi

賦值的使用,CHA定義變量ls,這個是我們的shell命令就需要使用反引號引用起來,一般比較長的目錄可以直接寫成變量的形式,在shell腳本中直接引用,這樣看起來比較簡潔,這裏是找出這個文件下以.yaml結尾的文件並統計大小和倒着排序

[root@zhaocheng ~]# cat fuzhi.sh 
#!/bin/bash

CHA=`ls`
DIR=/opt/k8s/ansible

echo $CHA
find $DIR -name "*.yaml" |xargs du -sh |sort -nr
[root@zhaocheng ~]# bash fuzhi.sh 
canshu.sh echo.sh fuzhi.sh tianqi.sh yum.sh
8.0K    /opt/k8s/ansible/ansible-k8s/ansible-install-k8s/roles/addons/files/kubernetes-dashboard.yaml
8.0K    /opt/k8s/ansible/ansible-k8s/ansible-install-k8s/roles/addons/files/kube-flannel.yaml
8.0K    /opt/k8s/ansible/ansible-k8s/ansible-install-k8s/roles/addons/files/ingress-controller.yaml
8.0K    /opt/k8s/ansible/ansible-k8s/ansible-install-k8s/roles/addons/files/coredns.yaml
4.0K    /opt/k8s/ansible/ansible-k8s/ansible-install-k8s/roles/master/files/kubelet-bootstrap-rbac.yaml
4.0K    /opt/k8s/ansible/ansible-k8s/ansible-install-k8s/roles/master/files/apiserver-to-kubelet-rbac.yaml

交互式設置變量read
常用參數

-p:給出提示符。默認不支持"\n"換行
-s:靜默模式。輸入的內容不會回顯在屏幕上
-t:給出超時時間,在達到超時時間時,read退出並返回錯誤
-n:限制讀取N個字符就自動結束讀取,如果沒有讀滿N個字符就按下回車或遇到換行符,則也會結束讀取
-N:嚴格要求讀滿N個字符才自動結束讀取,即使中途按下了回車或遇到了換行符也不結束。其中換行符或回車算一個字符
-a:將分裂後的字段依次存儲到指定的數組中,存儲的起始位置從數組的index=0開始
-p:給出提示符

read的基本用法

[root@zhaocheng ~]# cat read.sh 
#!/bin/bash
read -p  "請輸入你的名字:" lakey
read -s -p  "請輸入你的性別:" girl
read -s -p  "請輸入你有沒有對象:" ggg
echo
echo -e "\033[35m 你的名字是:$lakey \033[0m"
echo -e "\033[35m 你的性別是:$girl \033[0m"
echo -e "\033[35m 不,你不可能有對象:$ggg \033[0m"
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章