shell腳本編程基礎

 

 

 

 

 

 

一編程基礎

 

   1程序編程風格

 

 


程序:指令+數據java

 

程序編程風格:node


(1)過程式:以指令爲中心,數據服務於指令。python

 

程序員把主要的精力集中在程序指令上,一步步怎麼作的。好比C、C++符合人類處理事情的邏輯關係的,不過這適合簡單的事情。程序員

 

對於大型的應用程序的開發這種方法是很是難的,會產生混亂。web

 


(2)對象式:以數據爲中心,指令服務於數據。shell

經過指令處理數據,獲得咱們關心的結果,程序最重要的功能是在處理數據上。編程

 

對於大型的事是採用這種方法。好比蓋大樓要僱用一些團隊,把大的工做分解成小的工做。設計圖紙有專門的設計院來完成,搬磚要有專門的工人。vim

 

對於大的項目來講不太關注每一個流程了。更多的考慮把任務分包給具體的人,每一個團隊作本身的事,作完就好,不關心作事的方式。centos

 

就像有句話叫作只要白貓黑貓能抓住老鼠的就是好貓。數組

 

大項目使用的是面向對象,而小項目是面向過程。咱們如今編腳本仍是面向過程式的。

 

 

 

 

 

 

   2程序的執行方式

 


(1)計算機:運行二進制指令

 

計算機只能識別二進制。計算機真的要運行一個程序,要把人類可以理解的東西轉化成二進制。

 


(2)編程語言:

 

1低級:彙編

 

彙編語言也是字符串,和機器語言是一一對應的,要把彙編語言轉化成機器碼進行分析。

 

 

2高級:

 

<1>編譯

 

<1>編譯:高級語言-->編譯器-->目標代碼   好比java,C#

 

編譯型的語言要轉化成二進制的內容纔會執行,須要有編譯器生成二進制的東西。

 

好比ls命令是一個二進制的東西,是編譯完了的最終結果。

 

咱們看裏面的東西是亂碼的。

 

 

 

[root@centos73 ~]# cat  /bin/ls

 


 

 

 

 

 

 

<2>解釋


<2>解釋:高級語言-->解釋器-->機器代碼   好比shell, perl, python

 

 

 

對於解釋型語言,在運行的時候,系統後臺有一個解釋器,自動把文字的東西解釋成機器代碼。

 

雖然也是轉換成二進制的,可是是放在內存中的,不須要生成文件。

 

因此感受好像就是一個文本在運行。

 

而shell裏面的解釋器有不少,好比bash shell。

 

shell程序就是把咱們所學的命令按照邏輯關係寫到文本中。提供了編程能力,翻譯成機器碼解釋執行。

 

 

編譯是要人工去作,而解釋是系統自動完成的,因此在代碼出現問題須要修改編譯更麻煩。

 

Java,C語言事先要進行編譯一下,變成了看不懂的二進制的文檔,而不是解釋執行。

 

 

 

 

 

 

 

 

 

 

   3編程基本概念——編程邏輯處理方式

 

 

1順序執行。就是指令按照順序執行。

 

2循環執行。重複的執行某個指令,好比建立100個帳號。

 

3選擇執行。當知足某個條件執行一個指令,而當知足另一個條件的時候執行另外的指令。

 

shell編程:過程式、解釋執行


編程語言的基本結構:各類系統命令的組合,數據存儲:變量、數組,表達式: a + b,語句:if。




 

 

 

 

二shell腳本基礎

 

 

   1shell腳本介紹

 

 

規範的shell腳本的語法要求,包含一些命令或聲明,並符合必定格式的文本文件格式要求。


格式要求:首行shebang機制

 

#在英文裏面叫作sharp,!叫作bang.#!就是shebang

 

第一行要告訴shell,使用的是那種shell,對於其餘語言寫上本身語言的類型便可。

 


#!/bin/bash


#!/usr/bin/python


#!/usr/bin/perl 

 

 

 

 

 

 

   2shell腳本的用途

 

 

  1. 自動化經常使用命令,作事要3次以上建議寫腳本。
  2. 執行系統管理和故障排除
  3. 建立簡單的應用程序
  4. 處理文本或文件

 

 

 

 

 

   3shell腳本的執行原理

 

 

當執行一個命令的時候,先判斷是否是別名,內部命令。若是不是就看是不是外部命令,外部命令是對應PATH變量的路徑來找的。

 

在Linux裏面,執行命令是不會尋找當前目錄的

 

 

而當shell腳本運行時,它會先查找系統環境變量ENV裏面的PATH路徑。

 

該變量指定了環境文件(加載順序通常默認是/etc/profile、.bash profile.、~/.bashrc, /etc/bashrc等),在加載了上述環境變量文件後, shell就開始執行shell腳本中的內容。

 


shell腳本是從上至下、從左至右依次執行每一行的命令及語句的,即執行完了一個命令後再執行下一個。

 

 

若是在shell腳本中遇到子腳本(即腳本嵌套)時,就會先執行子腳本的內容,完成後再返回父腳本繼續執行父腳本內後續的命令及語句。

 


一般狀況下,在執行shell腳本時,會向系統內核請求啓動一個新的進程,以便在該進程中執行腳本的命令及子shell腳本。

 

 

 

基本流程如圖所示:

 

 

 

 

 

 

 

 

 PATH=/root/shell_scripts:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin

注意第1個路徑是我後來加的,爲了執行方便

[root@centos733 ~]# env
XDG_SESSION_ID=1 HOSTNAME=centos733.huawei.com SELINUX_ROLE_REQUESTED= TERM=xterm SHELL=/bin/bash HISTSIZE=1000 SSH_CLIENT=192.168.137.34 58583 22 SELINUX_USE_CURRENT_RANGE= SSH_TTY=/dev/pts/0 USER=root LS_COLORS=rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=01;05;37;41:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arc=01;31:*.arj=01;31:*.taz=01;31:*.lha=01;31:*.lz4=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.tzo=01;31:*.t7z=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.dz=01;31:*.gz=01;31:*.lrz=01;31:*.lz=01;31:*.lzo=01;31:*.xz=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.alz=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.cab=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.axv=01;35:*.anx=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=01;36:*.au=01;36:*.flac=01;36:*.mid=01;36:*.midi=01;36:*.mka=01;36:*.mp3=01;36:*.mpc=01;36:*.ogg=01;36:*.ra=01;36:*.wav=01;36:*.axa=01;36:*.oga=01;36:*.spx=01;36:*.xspf=01;36: MAIL=/var/spool/mail/root PATH=/root/shell_scripts:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin PWD=/root LANG=en_US.UTF-8 SELINUX_LEVEL_REQUESTED= HISTCONTROL=ignoredups SHLVL=1 HOME=/root LOGNAME=root SSH_CONNECTION=192.168.137.34 58583 192.168.137.73 22 LESSOPEN=||/usr/bin/lesspipe.sh %s XDG_RUNTIME_DIR=/run/user/0 _=/usr/bin/env

 

 

 

 

 

 

 

 

   4建立shell腳本的步驟

 

 

第一步:使用文本編輯器,好比常見的vim來建立文本文件。

 

 

第一行必須包括shell聲明序列#!/bin/bash

 

添加註釋,註釋以#開頭

 

 

第二步:運行腳本,給予執行權限,在命令行上指定腳本的絕對或相對路徑。直接運行解釋器,將腳本做爲解釋器程序的參數運行。

 

 

因爲系統默認的是使用bash,因此能夠省略不寫,可是把腳本拷到其餘的機器上,不必定使用的是這個bash。爲了不產生BUG建議都要寫。

 

爲了讓程序更易於維護,要加註釋,包括做者,版本號,功能等等。

 

注意shell自己是開源的,無法加密的。

 

 

 

 

 

   5shell腳本規範

 

 

 

腳本代碼開頭約定

一、第一行通常爲調用使用的語言

二、程序名,避免更改文件名爲沒法找到正確的文件

三、版本號

四、更改後時間

五、做者相關信息

六、該程序的做用,及注意事項

七、最後是各版本的更新簡要說明

 

 

 

 

 

   6shell腳本的基本結構

 

 

第一行  #!SHEBANG

變量 CONFIGURATION VARIABLES

函數 FUNCTION DEFINITIONS

主要代碼 MAIN CODE

 

 

 

 

 

   7shell腳本執行的方式

 

 

Shell腳本的執行一般能夠採用如下幾種方式


1 bash   script-name或sh script-name

 

這是當腳本文件自己沒有可執行權限(即文件權限屬性x位爲-號)時常使用的方法,或者腳本文件開頭沒有指定解釋器時須要使用的方法。

 

推薦使用這種方法

 

 


2 path/script-name或/script-name 

 

在當前路徑下執行腳本(腳本須要有執行權限),須要將腳本文件的權限先改成可執行(即文件權限屬性加x位),

 

 

具體方法爲chmod +x script-name,而後經過腳本絕對路徑或相對路徑就能夠直接執行腳本了。

 


在企業生產環境中,很多運維人員在寫完Shell腳本以後,因爲忘記爲該腳本設置執行權限,而後就直接應用了,結果致使腳本沒有按照本身的意願手動或定時執行,

 

對於這一點,避免出現該問題的方法就是用第1種方法替代第2種。

 

 

 


3 source script-name或. script-name

 

這種方法一般是使用source或"." (點號)讀入或加載指定的Shell腳本文件(如san.sh),而後,依次執行指定的Shell腳本文件san.sh中的全部語句。

 

這些語句將在當前父Shell腳本father.sh進程中運行(其餘幾種模式都會啓動新的進程執行子腳本)。

 

所以,使用source或「."能夠將san.sh自身腳本中的變量值或函數等的返回值傳遞到當前父Shell腳本father.sh中使用。

 

這是它和其餘幾種方法最大的區別。

 


source或「."命令的功能是:在當前Shell中執行source或「."加載並執行的相關腳本文件中的命令及語句,而不是產生一個子Shell來執行文件中的命令。

 

注意"."和後面的腳本名之間要有空格。

 


source或"."至關於PHP開發的include的功能。HTTP服務軟件Apache,Nginx等配置文件裏都支持這樣的用法。

 

 

 

 


4 sh<script-name或cat scripts-namelsh

 

一樣適用於bash,不過不常見

 

不用循環語句來實現精簡開機自啓動服務就是經過將全部字符串拼接爲命令的形式,而後經由管道交給bash操做

 

 

 

注意不寫路徑直接執行腳本,那麼就把腳本放到PATH變量裏面的路徑去,即便是在其餘的路徑也能夠執行。

[root@centos733 shell_scripts]# pwd
/root/shell_scripts
[root@centos733 shell_scripts]# echo $PATH /root/shell_scripts:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin

 

 

 

 

運行第1個腳本

注意最後找一個集中的目錄來存放本身寫的腳本,便於查看和備份

#!/bin/bash

# Filename: hel1o.sh

# Revision: 1.1

# Date: 2018/06/01

#Author: wangm

# Description: This is the first script

echo "hello world"
 

 

 

 

 

 

1 bash   script-name或sh script-name

 

腳本是在 shell_scripts目錄下寫的,可是是在root目錄下執行

[root@centos733 ~]# ll    shell_scripts/ -d
drwxr-xr-x. 3 root root 4096 Mar 14 21:50 shell_scripts/ [root@centos733 ~]# ll shell_scripts/hello.sh -rw-r--r--. 1 root root 161 Mar 14 21:50 shell_scripts/hello.sh [root@centos733 ~]# bash hello.sh hello world [root@centos733 ~]# cat shell_scripts/hello.sh #!/bin/bash #Author=wang # Filename: hel1o.sh # Revision: 1.1 # Date: 2018/06/01 #Author: wangm # Description: This is the first script echo "hello world"

 

 

 

 

 

 

2 path/script-name或/script-name 

[root@centos733 ~]# ./shell_scripts/hello.sh
-bash: ./shell_scripts/hello.sh: Permission denied
[root@centos733 ~]# cd  shell_scripts/ [root@centos733 shell_scripts]# pwd /root/shell_scripts  [root@centos733 shell_scripts]# ./hello.sh -bash: ./hello.sh: Permission denied  [root@centos733 shell_scripts]# ll hello.sh -rw-r--r--. 1 root root 161 Mar 14 21:50 hello.sh [root@centos733 shell_scripts]# chmod +x hello.sh [root@centos733 shell_scripts]# ./hello.sh hello world [root@centos733 shell_scripts]# cd [root@centos733 ~]# ./shell_scripts/hello.sh hello world [root@centos733 ~]# ./shell_scripts/hello.sh hello world  [root@centos733 ~]# ll shell_scripts/hello.sh -rwxr-xr-x. 1 root root 161 Mar 14 21:50 shell_scripts/hello.sh

 

 

 

 

 

 

 3 source script-name或. script-name

和法1同樣不須要加執行權限也能夠執行

[root@centos733 ~]# .  shell_scripts/hello.sh 
hello world
[root@centos733 ~]# source   shell_scripts/hello.sh hello world [root@centos733 ~]# chmod -x shell_scripts/hello.sh [root@centos733 ~]# ll shell_scripts/hello.sh -rw-r--r--. 1 root root 161 Mar 14 21:50 shell_scripts/hello.sh [root@centos733 ~]# . shell_scripts/hello.sh hello world [root@centos733 ~]# source shell_scripts/hello.sh hello world

 

 

 

 

 

 

 

   8腳本語法檢測和調試

 

 

1腳本語法檢測

bash -n    /path/to/some_script   

檢測腳本中的語法錯誤。注意bash -n對於語法錯誤是能夠查出來的,可是對於命令寫錯是不能查出來的。

 

 

 

2 調試執行

bash   -x     /path/to/some_script

 

 

 

編寫關於顯示操做系統各類信息的腳本

[root@centos733 shell_scripts]# cat  OS.sh 
#!/bin/bash #Description: show system info echo "The host is `hostname`" echo "The kernel version is `uname -r`" echo "The CPU is `lscpu | grep "Model name:" | tr -s ' ' | cut -d : -f2`" cat /proc/meminfo | head -n1 echo "The IP is `ifconfig ens33 | grep netmask | tr -s ' ' | cut -d " " -f3`" 

 

 

 

 

 1腳本語法檢測

[root@centos733 shell_scripts]# pwd
/root/shell_scripts
[root@centos733 shell_scripts]# bash  -n  OS.sh 

 

 

 

 

2 調試執行

 

跟蹤每一步的執行結果。能夠看出命令是分解執行的,同一行也是這樣。

命令嵌套,因此看到是先執行裏面的hostname,而後執行外面的echo

[root@centos733 shell_scripts]# bash  -x   OS.sh 
++ hostname
+ echo 'The  host is centos733.huawei.com'
The  host is centos733.huawei.com
++ uname -r + echo 'The kernel version is 3.10.0-862.el7.x86_64' The kernel version is 3.10.0-862.el7.x86_64 ++ lscpu ++ grep 'Model name:' ++ tr -s ' ' ++ cut -d : -f2 + echo 'The CPU is Intel(R) Core(TM) i7-7500U CPU @ 2.70GHz' The CPU is Intel(R) Core(TM) i7-7500U CPU @ 2.70GHz + cat /proc/meminfo + head -n1 MemTotal: 997980 kB ++ grep netmask ++ cut -d ' ' -f3 ++ tr -s ' ' ++ ifconfig ens33 + echo 'The IP is 192.168.137.73' The IP is 192.168.137.73

 

 

 

 

 

 

 

由於hostname是一個命令,咱們用echo調用他是要加上反引號,爲了看起來更清晰,使用單引號引發來。

 

顯示內核版本的命令是uname   -r

 

顯示一下CPU的型號

[root@centos73 ~]# lscpu

Architecture:          x86_64

CPU op-mode(s):        32-bit, 64-bit

Byte Order:            Little Endian

CPU(s):                1

On-line CPU(s) list:   0

Thread(s) per core:    1

Core(s) per socket:    1

Socket(s):             1

NUMA node(s):          1

Vendor ID:             GenuineIntel

CPU family:            6

Model:                 142

Model name:            Intel(R) Core(TM) i7-7500U CPU @ 2.70GHz

 

 

 

 

查看內存,使用命令free

顯示當前系統的地址,調用命令是要在命令的左右兩邊加上反單引號。

[root@centos73 ~]# free  -h     -h, --human         show human-readable output

              total        used        free      shared  buff/cache   available

Mem:           992M        169M         82M         13M        739M        623M

Swap:          3.0G        520K        3.0G

 

 

[root@centos73 ~]# cat /proc/meminfo

MemTotal:        1015828 kB

MemFree:           84564 kB

MemAvailable:     638036 kB

Buffers:              36 kB

Cached:           656816 kB

SwapCached:          216 kB

Active:           333592 kB
相關文章
相關標籤/搜索