Linux - Shell 變量

        變量是暫時存儲數據的地方及數據標記,所存儲的數據存在於內存空間中,經過正確地調用內存空間中變量的名字就能夠取出與變量對應的數據。使用變量最大的好處就是使程序開發更爲方便,同時,在編程中如不使用變量也很難完成相關程序開發工做。簡單地說,變量就是用一個固定的字符串(字符、數字等組合)代替更多、更復雜的內容,該內容裏可能還包含變量、路徑、字符串等其餘的內容。linux

        默認狀況下,在 bash Shell 中是不會區分變量類型;這和其餘強類型語言(例如:Java/C 語言)是有區別的。固然也可使用 declare 顯示定義變量的類型,來指定 Shell 變量類型,但通常狀況下沒有這個需求。Shell 變量可分爲兩類:環境變量(全局變量)和普通變量(局部變量)。shell

1、環境變量

        環境變量也可稱爲全局變量,能夠在建立它們的 Shell 及其派生出來的任意子進程 Shell 中使用,環境變量又可分爲自定義環境變量和bash 內置的環境變量。編程

        環境變量通常是指用 export 內置命令導出的變量,用於定義 Shell 的運行環境,保證 Shell 命令的正確執行。Shell 經過環境變量來肯定登錄用戶名、命令路徑、終端類型、登錄目錄等,全部的環境變量都是系統全局變量,可用於全部子進程中,這包括編輯器、Shell 腳本和各種應用。環境變量能夠在命令行中設置和建立,但用戶退出命令行時這些變量值就會丟失,因此在用戶家目錄下的 .bash_profile 或 bashrc (非用戶登陸模式特有,例如遠程SSH) 文件中,或者,在全局配置 /etc/profile 文件中定義或 /etc/bashrc (非用戶登陸模式特有,例如遠程SSH) 。在將環境變量放入上述的文件中後,每次用戶登陸時這些變量都將被初始化,也就是能夠永久保存環境變量不會隨着用戶退出命令行這些變量值就會丟失。vim

        按照系統規範,全部環境變量的名字均採用大寫形式。在將環境變量應用於用戶進程程序以前,都應該用 export 命令導出定義,例如:bash

# .bash_profile

# Get the aliases and functions
if [ -f ~/.bashrc ]; then
        . ~/.bashrc
fi

# User specific environment and startup programs

PATH=$PATH:$HOME/.local/bin:$HOME/bin

export PATH
JAVA_HOME=/home/redhat/jdk/jdk1.8.0_121
CLASSPATH=$JAVA_HOME/lib/
PATH=$JAVA_HOME/bin:$PATH
export PATH JAVA_HOME CLASSPATH

#zookeeper env
export ZOOKEEPER_HOME=/home/redhat/zookeeper
export PATH=$ZOOKEEPER_HOME/bin:$PATH

        在查看設置的變量時,有3個命令能夠顯示變量的值:set、env 和 declare( 代替早期的 typeset )。set 命令輸出全部的變量,包括全局變量和局部變量;env 命令只顯示全局變量;declare 命令輸出全部的變量、函數、整數和已導出的變量。set -o 命令顯示 bash Shell 的全部參數配置信息。less

[redhat@BING ~]$ env|tail
HOME=/home/redhat
LOGNAME=redhat
QTLIB=/usr/lib64/qt-3.3/lib
CLASSPATH=/home/redhat/jdk/jdk1.8.0_121/lib/
SSH_CONNECTION=10.11.63.25 52141 10.100.12.81 22
LESSOPEN=||/usr/bin/lesspipe.sh %s
XDG_RUNTIME_DIR=/run/user/1000
DISPLAY=localhost:12.0
QT_PLUGIN_PATH=/usr/lib64/kde4/plugins:/usr/lib/kde4/plugins
_=/usr/bin/env
[redhat@BING ~]$ declare|tail
{
    local quoted=${1//\'/\'\\\'\'};
    printf "'%s'" "$quoted"
}
quote_readline ()
{
    local quoted;
    _quote_readline_by_ref "$1" ret;
    printf %s "$ret"
}
[redhat@BING ~]$ set -o|head
allexport       off
braceexpand     on
emacs           on
errexit         off
errtrace        off
functrace       off
hashall         on
histexpand      on
history         on
ignoreeof       off

1.1 自定義環境變量

1.1.1 設置環境變量

         設置環境變量的三種方法:編輯器

# export 命令和 declare 命令的格式以下:

# 一、在設置變量時使用 export 命令
export 變量名=value
# 二、再給變量賦值以後,再使用 export 命令
變量名=value; 
export 變量名
# 三、帶 -x 選項的 declare 內置命令也可 (此處不要在變量名前面加$)
declare -x 變量名=value

        全局環境變量的配置:函數

# 常見的全局配置變量的配置文件
/etc/profile

/etc/bashrc         # 推薦在此文件中優先設置

# 若要在登陸後初始化或顯示加載內容,則把腳本文件放在 /etc/profile.d 下便可(無須加執行權限)
/etc/profile.d

        若要在登陸後初始化或顯示加載內容,則把腳本文件放在 /etc/profile.d 下便可(無須加執行權限),例如,設置登陸提示:工具

        1)第一種是在 /etc/motd 裏增長提示字符串spa

[redhat@BING ~]$ cat /etc/motd
[redhat@BING ~]$ vim /etc/motd
[redhat@BING ~]$ sudo vim /etc/motd
[redhat@BING ~]$ cat /etc/motd
Welcome to BING Linux.
[redhat@BING ~]$

        2) 第二種是在 /etc/profile.d/ 下面增長以下腳本

[redhat@SHOUFUAP ~]$ cat /etc/profile.d/welcome.sh  # 展現welcome.sh腳本內容
Welcome to BING Linux.

1.1.2 顯示或取消環境變量

        1)經過 echo 或 printf 命令打印環境變量

[redhat@BING ~]$ echo $HOME
/home/redhat
[redhat@BING ~]$ echo $UID
1000
[redhat@BING ~]$ echo $PWD
/home/redhat
[redhat@BING ~]$ echo $SHELL
/bin/bash
[redhat@BING ~]$ echo $USER
redhat
[redhat@BING ~]$ printf "$HOME\n"
/home/redhat
[redhat@BING ~]$

# printf 是一個更復雜的格式化打印內容工具
# $HOME: 用戶登陸時進入的目錄
# $UID: 當前用戶的 UID (用戶標識),至關於 id-u
# $PWD: 當前工做目錄的絕對路徑名
# $SHELL: 當前 SHELL
# $USER: 當前用戶

        在寫 Shell 腳本時能夠直接使用系統默認的環境變量,通常狀況下時是不須要從新定義的,在使用定時任務等執行 Shell 腳本時建議在腳本中從新定義。

        能夠用 env 或 set 顯示默認的環境變量;也能夠用 unset 消除本地變量和環境變量。

1.1.3 環境變量初始化與對應文件的生效順序

    在登陸Linux系統並啓動一個bash shell時,默認狀況下bash會在若干個文件中查找環境變量的設置。這些文件可統稱爲系統環境變量。bash檢查的環境變量文件的狀況取決於系統運行shell的方式。
系統運行shell的方式通常有三種:
    1) 經過系統用戶登陸後默認運行的shell
    2) 非登陸交互式運行shell
    3) 執行腳本運行非交互式shell
    當用戶登陸Linux系統時,shell會做爲登陸shell啓動。登陸 Shell 讀取環境變量文件的流程以下:

 

 

 

 

 

 

 

 

 

 

         用戶登陸系統後首先會加載/etc/profile全局變量文件,這是Linux系統上默認的shell主環境變量文件。系統上每一個用戶登陸都會加載這個文件。當加載完/etc/profile文件後,纔會執行/etc/profile.d目錄下的腳本文件。以後開始運行$HOME/.bash_profile(用戶環境變量文件),在這個文件中,又會去找$HOME/.bashrc(用戶環境變量文件),若是有則執行,若是沒有則不執行。在$HOME/.bashrc文件中又會去找/etc/bashrc(全局環境變量文件),若是有則執行,若是沒有則不執行。
    若是用戶的shell不是登陸時啓動的,非登陸shell只會加載$HOME/.bashrc(用戶環境變量文件),並會去找/etc/bashrc(全局環境變量文件)。若是但願在登陸shell下也能夠讀到設置的環境變量等內容,就須要將變量設定等寫入$HOME/.bashrc或者/etc/bashrc,而不是$HOME/.bash_profile或/etc/profile。
 

1.2 普通變量

1.2.1 定義本地變量

        本地變量(局部變量) 在用戶當前 Shell 生存期的腳本中使用。變量名通常是由字母、數字、下劃線組成的,能夠以字母或下劃線開頭;變量的內容能夠用單引號或雙引號引發來,也可不加引號,但三者含義是不一樣的。爲普通變量的定義賦值,通常有如下三種寫法:   

# 賦值時不加引號
變量名=value

# 賦值時加單引號
變量名='value'

# 賦值時加雙引號
變量名="value"

        採用不一樣的方式對普通變量進行定義的差別以下( $變量名錶示輸出變量,能夠用 $變量名 和 ${變量名} ):

        1) 定義 x 變量的方式是不加任何引號直接定義變量的內容,當內容爲簡單連續的數字、字符串、路徑名時,能夠這樣用;其特色:不加引號時,值裏有變量的會被解析後輸出

# 定義變量
x=192.168.1.1-$x

# 輸出結果($x的值被解析)
x=192.168.1.1-192.168.1.1

        2) 定義 y 變量的方式是經過的的單引號定義,其特色:輸出變量內容時單引號裏是什麼就輸出什麼,即便內容中有變量和命令(命令須要反引號`` 引發來)也會原樣輸出

# 定義變量
y='192.168.1.1-$x'

# 輸出結果($x的值不會被解析)
y=192.168.1.1-$x

        3) 定義 z 變量的方式是經過雙引號定義變量,其特色:輸出變量內容時引號裏的變量及命令會通過解析後在輸出內容,而不是把雙引號中的變量名及命令(命令須要反引號`` 引發來)

# 定義變量
z=192.168.1.1-$x

# 輸出結果($x的值被解析)
z=192.168.1.1-192.168.1.1-192.168.1.1

        因此數字內容的變量定義能夠不加引號,其餘沒有特別要求的字符串等定義最好都加上雙引號,若是真的的須要原樣輸出就加單引號。同時,把一個命令的結果做爲變量的內容賦值的方法在腳本開發中也是很經常使用的。

        對須要獲取命令結果的變量內容賦值的常見方法有兩種:

# 把命令用反引號引發來(容易和單引號混淆)
變量名=`ls`

# 把命令用 $() 括起來
變量名=$(ls)


[redhat@BING jdk]$ ls
jdk1.8.0_121  jdk-8u121-linux-x64.tar.gz
[redhat@BING jdk]$ CMD=`ls`
[redhat@BING jdk]$ echo $CMD
jdk1.8.0_121 jdk-8u121-linux-x64.tar.gz
[redhat@BING jdk]$ echo ${CMD}
jdk1.8.0_121 jdk-8u121-linux-x64.tar.gz
[redhat@BING jdk]$ CMD_PWD=$(pwd)
[redhat@BING jdk]$ echo $CMD_PWD
/home/redhat/jdk
[redhat@BING jdk]$ echo ${CMD_PWD}
/home/redhat/jdk
[redhat@BING ~]$ echo H=$(date)
H=Thu Oct 4 13:22:58 CST 2018
[redhat@BING ~]$ echo zcf etc_$(date +%F).tar.gz /etc           # tar: 從成員名中刪除開頭的「/」 ; tar: 從硬鏈接目標中刪除開頭的「/」
zcf etc_2018-10-04.tar.gz /etc
[redhat@BING ~]$ H=$(uname -n)
[redhat@BING ~]$ echo ${H}
BING
[redhat@BING ~]$ echo zcf $H.tar.gz /etc/services               # tar: 從成員名中刪除開頭的「/」
zcf BING.tar.gz /etc/services
[redhat@BING ~]$

        echo 、sed 、grep 調用是符合上述結論的,可是當使用 awk 調用 Shell 中的變量時,會有一些特殊用法。就是無論變量如何定義、賦值,除了加單引號之外,利用 awk 直接獲取變量的輸出,結果都同樣,所以,在 awk 取用 Shell 變量時,最好是先用 echo 加符號輸出變量,而後經過管道給 awk ,進而控制變量的輸出結果。

相關文章
相關標籤/搜索