shell腳本之變量與狀態碼

目錄:

   前言

如何創建一個腳本

腳本調試

變量相關

變量的命令規則

bash中變量的種類

本地變量

環境變量

只讀和位置變量

位置變量

查詢變量

進程的退出狀態與狀態碼

前言

linux管理中,shell腳本很是重要,它可以幫助我們完成很多繁瑣的工作,專注於更重要的事情上來,腳本的學習也是我們學習linux中所要遇到的比較困難的部分,因爲它需要對vim,正則,邏輯,程序化語言有一定的熟悉,shell編程是過程式,解釋執行的。它包括各種系統指令的組合,數據存儲(變量,數組)、表達式、語句。

   shell腳本中,包含一些命令或聲明,並符合一定格式的文本文件,在首行是shebang機制,如:

#!/bin/bash

#!/usr/bin/python

#!/usr/bin/perl

腳本在開頭查找執行本腳本的程序,此程序就在第一行命令。Shell腳本經常用於自動化常用命令,執行系統管理和故障排除,創建簡單的應用程序,處理文本或文件。

如何創建一個腳本

第一步,使用文本編輯器(vim)創建一個文件,一般都是以.sh結尾,在第一行必須包括shell聲明#!(即shebang機制)我們一般使用#!/bin/bash

[root@CT71 bin]# vim test.sh
 1 #!/bin/bash
 2 ~                                                                                                    
 3 ~                                                                                                    
 4 ~                                                                                                    
 5 ~                                                                                                    
 6 ~                                                                                                    
 7 ~                                                                                                    
 8 ~                                                                                                    
 9 ~                                                                                                    
10 ~                                                                                                    
11 ~                                                                                                    
12                                                                                                 
13 -- INSERT --                                                                   1,12   All

第二步,添加註釋,shell腳本中的註釋都是以#開頭,後面跟上註釋內容(一般註釋寫什麼,我們一會兒就會說到)

1 #!/bin/bash
2 #Filename: test.sh
3 #Revision: 1.0
4 #Date: 2017-8-2
5 #Author: hahaha
6 #Description: ################ 
~
~
~

 第三步,編寫腳本內容,腳本內容可以寫我們常用的一些命令,比如查找我們磁盤中使用量最大的百分比等

  1 #!/bin/bash
  2 #Filename: disk.sh
  3 #Revision: 1.0
  4 #Date: 2017-8-2
  5 #Author: hahaha
  6 #Dessciption: 
  7 
  8 df | grep "dev/sd" | tr -s " " % | cut -d"%" -f5 | sort -nr | head -1
~                                                                                                    
~                                                                                                    
~                                                                                                    
~                                                                                                    
~                      

第四步,給予腳本執行權限,即chmod +x shellname.sh,最後我們就可以執行我們的腳本了

[root@CT71 bin]# ll | grep "test.sh"
-rw-r--r--. 1 root root    0 Aug  3 16:06 test.sh
[root@CT71 bin]# chmod +x test.sh
[root@CT71 bin]# ll | grep "test.sh"
-rwxr-xr-x. 1 root root    0 Aug  3 16:06 test.sh 

接下來我們說說們可以在註釋裏寫啥東西。

1.  第一行一般爲調用使用的語言

2.  程序名,避免更改文件名爲無法找到正確的文件

3.  版本號

4.  更改後的時間

5.  作者相關信息

6.該程序的作用,及注意事項

7. 最後是各版本的更新簡要說明

比如說:      

1 #!/bin/bash
2 # Filename: hello.sh
3 # Revision: 1.1
4 # Date: 2017/06/01
5 # Author: wang
6 # Description: This is the first script 

腳本調試

我們咋運行腳本之前,可以對腳本進行調試,這樣可以保證我們的腳本出錯的機率更低,一般我們常用的有兩個參數:

檢測腳本中的語法錯誤

bash -n /path/to/some_script

調試執行

bash -x /path/to/some_script

[root@CT71 bin]# bash -x link.sh 
+ netstat -tn
+ grep tcp
+ cut -d: -f6
+ sort -nr
+ uniq -c
+ tr -s ' ' :
      1 192.168.111.1

接下來我們開始與腳本內容相關的知識,基礎知識包括變量(變量的種類,變量的命令規則,本地變量,環境變量,位置變量),執行後的狀態及狀態碼,算數運算與賦值。

變量相關

shell腳本中的變量是弱類型的變量,語言的運行時會隱式做數據類型轉換。無須指定類型,默認均爲字符型;參與運算會自動進行隱式類型轉換,變量無須事先定義可直接調用。

變量的命令規則

1.  不能使程序中的保留字:例如if, for

2.  只能使用數字、字母及下劃線,且不能以數字開頭

3. 見名知義

4.  統一命名規則:駝峯命名法

1 for:錯誤
2 23var:錯誤
3 ip_w:正確
4 var:正確
5 _min:正確
6 someIp:正確

bash中變量的種類

根據變量的生效範圍等標準:

本地變量:生效範圍爲當前shell進程;對當前shell之外的其它shell進程,包括當前shell的子shell進程均無效

環境變量:生效範圍爲當前shell進程及其子進程局部變量:生效範圍爲當前shell進程中某代碼片斷(通常指函數)

位置變量: $1, $2, ...來表示,用於讓腳本在腳本代碼中調用通過命令行傳遞給它的參數

特殊變量:

 $?, $0, $*, $@, $#,$$

 

在這些變量中,本地變量僅對當前shell有效,對子shell是沒有效的。而環境變量對當前shell及其子shell都有效,我們可以用env查詢所有的環境變量,用set查詢本地變量和環境,我們有一點需要知道,在linux變量聲明以後會一直存在,除非我們把他們給刪除掉,刪除變量我們可以用unset varname

[root@CT71 bin]# echo $A
string
[root@CT71 bin]# unset A
[root@CT71 bin]# echo $A

[root@CT71 bin]# set | grep "^A"
ABRT_DEBUG_LOG=/dev/null
刪除了A變量

 

本地變量

設置變量:

   (1) 可以是直接字串; name=root"

(2) 變量引用: name="$USER"

(3) 命令引用: name=`COMMAND` name=$(COMMAND)

引用變量:

   ${varname}

$varname

“$varname”

[root@CT71 bin]# myName=BUG
[root@CT71 bin]# echo $myName
BUG
[root@CT71 bin]# echo "$myName"
BUG
[root@CT71 bin]# echo ${myName}
BUG

"":弱引用,其中的變量引用會被替換爲變量值

'':強引用,其中的變量引用不會被替換爲變量值,而保持原字符串

[root@CT71 bin]# echo "$USER"
root
[root@CT71 bin]# echo '$USER'
$USER

 

轉譯:

\ 完全轉譯

""部分轉譯 \ ` ! $(""無法轉譯的字符)

'' 完全轉譯

轉譯的原因是因爲有些字符在linux下有特殊含義,但是,我們又需要用到它普通意義,所以我們需要對他們轉譯成非特殊字符供我們使用。

[root@CT71 app]# echo "$20.0"
0.0
[root@CT71 app]# echo "\$20.0"
$20.0
[root@CT71 app]# echo '$20.0'
$20.0
[root@CT71 app]# echo "!ll"
echo "ll"
ll
[root@CT71 app]# echo '!ll'
!ll

環境變量

環境變量的聲明:

   export name=value

declare -x name=value

環境變量的引用:

   $name

${name}

在前面我們已經說過如何查看我們的變量,但是,查看環境變量的命令還有幾個,如:envprintenvexportdeclare –x,在bash中還有一些內建的環境變量

PATH:命令查找的路徑

SHELL:我們使用的shell

USER:當前用戶名

UID:當前用戶UID

HOME:家目錄

PWD:當前工作目錄

SHLVL:當前所在的幾級shell

LANG:使用的字符集

MAIL:郵箱路徑

HOSTNAME:主機名

HISTSIZE:歷史命令記錄長度

_:上次執行的命令

 

[root@CT71 app]# env
XDG_SESSION_ID=612
HOSTNAME=CT71  -----------------------------------------------------------------------主機名
SELINUX_ROLE_REQUESTED=
TERM=xterm
SHELL=/bin/bash  ---------------------------------------------------------------------使用的shell
HISTSIZE=1000  -----------------------------------------------------------------------歷史命令記錄長度
SSH_CLIENT=192.168.111.1 52880 22
SELINUX_USE_CURRENT_RANGE=
SSH_TTY=/dev/pts/2
USER=root  ---------------------------------------------------------------------------當前用戶名
LS_COLORS=rs=0:di=01;34:ln=01;36:mh=00
... ...
MAIL=/var/spool/mail/root --------------------------------------------------------------郵箱路徑
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin  --------------------命令查找路徑
PWD=/app  ----------------------------------------------------------------------------當前的工作目錄
LANG=en_US.UTF-8  --------------------------------------------------------------------使用的字符集
... ...

 SHLVL=1  -----------------------------------------------------------------------------當前所在的幾級shell
 HOME=/root  --------------------------------------------------------------------------當前用戶家目錄
 LOGNAME=root
 SSH_CONNECTION=192.168.111.1 52880 192.168.111.110 22
 LESSOPEN=||/usr/bin/lesspipe.sh %s
 XDG_RUNTIME_DIR=/run/user/0
 OLDPWD=/root/bin
 _=/usr/bin/env  ----------------------------------------------------------------------上次執行的命令

 

只讀和位置變量

我們可以在linux中設置只讀變量,它的特點是隻能聲明,但不能修改和刪除

聲明只讀變量:

   readonly name

   declare –r name

查看只讀變量:

   readonly –p

[root@CT71 app]# readonly H=2134
[root@CT71 app]# H=werq
-bash: H: readonly variable
[root@CT71 app]# readonly -p
declare -r BASHOPTS="checkwinsize:cmdhist:expand_aliases:extglob:extquote:force_fignore:histappend:interactive_comments:login_shell:progcomp:promptvars:sourcepath"
declare -ir BASHPID
declare -r BASH_COMPLETION_COMPAT_DIR="/etc/bash_completion.d"
declare -ar BASH_REMATCH='()'
declare -ar BASH_VERSINFO='([0]="4" [1]="2" [2]="46" [3]="1" [4]="release" [5]="x86_64-redhat-linux-gnu")'
declare -ir EUID="0"
declare -r H="2134"
declare -ir PPID="57929"
declare -r S
declare -r SHELLOPTS="braceexpand:emacs:hashall:histexpand:history:interactive-comments:monitor"
declare -ir UID="0"
[root@CT71 app]# unset -f S  刪除只讀變量
[root@CT71 app]# echo $S

[root@CT71 app]# 

declare是一個shell的內建命令,用來顯示所有變量屬性和和值的,它還有一些常用的參數,比如上面的declare –r是用來設置只讀變量的,declare –f不僅顯示變量,還顯示函數,還有declare –x設置環境變量等

位置變量

位置變量其實就是在腳本代碼中調用通過命令行傳遞給腳本的參數。我們可以通過外在的參數傳遞給腳本以實現與腳本的交互操作,增強腳本功能。

   在腳本中的$1,$2,$3…分別對應着腳本外面的1個,第2個,第3參數,$0代表的是命令本身,$*是傳遞給腳本的所有參數,全部參數合爲一個字符串

$@是傳遞給腳本的所有參數,每個參數爲獨立字符串,$#是傳遞給腳本的參數的個數($@ $* 只在被雙引號包起來的時候纔會有差異)

set -- 清空所有位置變量

  1 #!/bin/bash
  2 
  3 echo "$1"
~                                                                                                    
~  
-------------------------------------------
[root@CT71 app]# chmod +x test.sh 
[root@CT71 app]# ll
total 4
-rwxr-xr-x. 1 root root 23 Aug  3 19:22 test.sh
[root@CT71 app]# ./test.sh Hello
Hello
  1 #!/bin/bash
  2 echo "filename :$(basename $0)"
~                                                                                                    
~                                                                                                    
~      
-----------------------------------------

[root@CT71 app]# ./test2.sh
filename :test2.sh

  1 #!/bin/bash     #tt1.sh   
  2 ./tt2.sh "$@"
~                                                                                                    
~                 
  1 #!/bin/bash    #tt2.sh    
  2 
  3 echo "$@"
~             
[root@CT71 app]# ./tt1.sh 1 2 3 4 5
1 2 3 4 5
---------------------------------------------------------------------
  1 #!/bin/bash     #tt1.sh   
  2 ./tt2.sh "$#"
~                                                                                                    
~                 
  1 #!/bin/bash    #tt2.sh    
  2 
  3 echo "$#"
~             
[root@CT71 app]# ./tt1.sh 1 2 3 4 5
1

由於我不是在PATH所在的路徑下執行的腳本所以直接執行腳本是找不到的,必須要跟上確定的路徑./tt2.sh就是在本目錄下執行tt2.sh腳本

查詢變量

本地變量的查詢

   set (即查本地,也查環境)

[root@CT71 app]# set | grep -C 4 "^PWD"
PROMPT_COMMAND='printf "\033]0;%s@%s:%s\007" "${USER}" "${HOSTNAME%%.*}" "${PWD/#$HOME/~}"'
PS1='[\u@\h \W]\$ '
PS2='> '
PS4='+ '
PWD=/app
SELINUX_LEVEL_REQUESTED=
SELINUX_ROLE_REQUESTED=
SELINUX_USE_CURRENT_RANGE=
SHELL=/bin/bash

環境變量的查詢

env

printenv

export

declare -x

[root@CT71 app]# printenv
XDG_SESSION_ID=612
HOSTNAME=CT71
SELINUX_ROLE_REQUESTED=
TERM=xterm
SHELL=/bin/bash
HISTSIZE=1000
SSH_CLIENT=192.168.111.1 52880 22
SELINUX_USE_CURRENT_RANGE=
... ...

進程的退出狀態與狀態碼

我們在系統中沒執行一個命令都會開闢一個進程,配置一個PID,當程序運行結束後,即進程結束後,都會返回一個值給變量“?”,通過返回的值,我們就可以瞭解到這個進程執行的結果如何,在返回的中,0 代表執行成功,1-255代表着不同的失敗$?變量保存着最近的命令執行後的狀態。

除了程序自動的賦值外,我們也可以手動自定義程序退出的狀態碼,特別是在我們寫腳本時,通過條件語句進行判斷時,自定義的退出碼就派上大用場。

自定義退出狀態碼:

   exit[n] n={1..255}

注意:腳本中一旦遇到exit命令,腳本會立即終止;終止退出狀態取決於exit命令後面的數字

注意:如果未給腳本指定退出狀態碼,整個腳本的退出狀態碼取決於腳本中執行的最後一條命令的狀態碼

  1 #!/bin/bash
  2 
  3 echo "Myname is Tony!"
  4 
  5 exit 1
  6 
  7 echo "Show my name"
~                                                                                                    
~  
--------------------------------------------------
[root@CT71 app]# chmod +x tt3.sh 
[root@CT71 app]# ./tt3.sh 
Myname is Tony!

在這我們多說一點東西,如何查看進程以及PID,這裏有幾個變量和命令,我們來看一下:

變量$$:查看當前的PID

PPID:查看父進程的PID

SHLVL:顯示當前的shell是幾級shell

pstree:顯示進程樹

    -p:同時顯示進程的PID

   ps –ef :顯示進程信息

 

[root@CT71 app]# echo $$
57933
[root@CT71 app]# echo $PPID
57929
[root@CT71 app]# pstree -p | grep -C 2 "bash"
           |                `-{rsyslogd}(2281)
           |-smartd(577)
           |-sshd(1401)---sshd(57929)---bash(57933)-+-grep(61485)
           |                                        `-pstree(61484)
           |-systemd-journal(367)
[root@CT71 app]# echo $SHLVL
1
[root@CT71 app]# ps -ef | grep "bash"
root        607      1  0 Jul31 ?        00:00:14 /bin/bash /usr/sbin/ksmtuned
root      57933  57929  0 14:09 pts/2    00:00:01 -bash
root      61495  57933  0 20:05 pts/2    00:00:00 grep --color=auto bash

 

 

 

 

發佈了52 篇原創文章 · 獲贊 5 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章