SHELL指令碼攻略(學習筆記)--1.4 變數(基礎),shell--1.4

來源:互聯網
上載者:User

SHELL指令碼攻略(學習筆記)--1.4 變數(基礎),shell--1.4

本文目錄:

1.4.1 環境變數

1.4.2 普通變數

1.4.3 修改變數的生命週期和範圍

1.4.4 擷取變數的長度

1.4.5 declare聲明變數

1.4.6 位置變數和特殊變數

1.4.7 shift輪替變數

1.4.8 shell其它基礎

1.4.9 變數的切分、提取和替換

變數存在於記憶體中。假設變數str,設定或修改變數屬性時,不帶$號,只有引用變數的值時才使用$號。也就是說在記憶體中,標記變數的變數名稱是str,而不是$str

1.4.1 環境變數

環境變數就是運行在"環境"內容相關的,在這個上下文都可以引用。例如,常見的cd、ls等命令嚴格來說應該使用絕對路徑如/bin/ls來執行,由於/bin目錄加入到了PATH環境變數中,系統自己會去尋找PATH下的路徑是否有該命令。

環境變數常用大寫字母表示。常見的環境變數有HOSTNAME、SHELL、HISTSIZE、USER、PATH、PWD、LANG、HOME、LOGNAME。分別表示當前主機名稱、SHELL的路徑即bash的類型、history儲存多少記錄、目前使用者名、自動搜尋路徑、目前的目錄、使用的語系(臨時修改語系時就改這個變數)、目前使用者的家目錄、當前登入的使用者。

使用env或者export可以查看目前使用者的環境變數。

[root@xuexi ~]# envXDG_SESSION_ID=411HOSTNAME=xuexi.longshuai.comTERM=linuxSHELL=/bin/bashHISTSIZE=1000SSH_CLIENT=172.16.10.1 10171 22QTDIR=/usr/lib64/qt-3.3QTINC=/usr/lib64/qt-3.3/includeSSH_TTY=/dev/pts/0QT_GRAPHICSSYSTEM_CHECKED=1USER=rootLS_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/rootPATH=/usr/lib64/qt-3.3/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin:/usr/local/sersync:/root/binPWD=/rootLANG=en_US.UTF-8HISTCONTROL=ignoredupsSHLVL=1HOME=/rootLOGNAME=rootQTLIB=/usr/lib64/qt-3.3/libSSH_CONNECTION=172.16.10.1 10171 172.16.10.3 22LESSOPEN=||/usr/bin/lesspipe.sh %sXDG_RUNTIME_DIR=/run/user/0_=/usr/bin/env

使用echo可以輸出變數的值。

[root@xuexi ~]# echo $PATH /usr/lib64/qt-3.3/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin

例如,在PATH環境變數中新加入一個目錄/usr/local/mysql/bin。

[root@xuexi tmp]# PATH=/usr/local/mysql/bin:$PATH

這裡也能看到兩個PATH第一個沒使用$,第二個使用了。當對變數本身進行操作,則不使用$,當對變數值進行操作,則使用$

1.4.2 普通變數

指令碼語言是弱類型的語言,變數通常不需要特地聲明甚至不需要初始化,在指令碼運行時由解譯器進行解釋運算,解譯器知道變數在什麼時候是什麼類型,所以直接賦值使用即可。bash中,變數預設都是字串類型,不論是否使用引號賦值,都以字串方式儲存。

變數賦值方式:str=value,其實是set str=value,省略了set關鍵字。注意等號左右沒有空格。如果有空格就是進行比較子的比較運算了。

變數引用方式:$str或者${str},例如echo "the var is ${str}"。

[root@xuexi tmp]# str='Hello World!'[root@xuexi tmp]# echo "We will say ${str}"We will say Hello World! 

釋放變數:unset str,注意變數名前不加首碼$。

[root@xuexi ~]# unset str

查看所有的變數:不接任何參數的set或者declare命令,輸出結果中包含了普通變數和環境變數。

定義唯讀變數:readonly str。這時將無法修改變數值也無法unset變數,只有重新登入shell才能繼續使用唯讀變數。

臨時將普通變數升級為環境變數:export str或者賦值時export str="value",這樣$str就可以在當前shell和子shell中使用,但是退出指令碼或者重新登入shell都會取消export效果。

[root@xuexi ~]# str='Hello World!';echo $strHello World![root@xuexi ~]# bash            # 開啟子shell[root@xuexi ~]# echo ${str}     # 子shell中查看變數結果發現沒有該變數。

在子shell中查看變數,結果竟然發現沒有該變數。這是因為$str的範圍只在當前shell,要想在子shell中也能引用普通變數,則需要使用export升級為環境變數。

[root@xuexi ~]# exit   # 退出子shell[root@xuexi ~]# export str # 回到父shell升級該變數[root@xuexi ~]# bash[root@xuexi ~]# echo $strHello World!

1.4.3 修改變數的生命週期和範圍

普通的變數在指令碼結束或退出登入後就失效,並且只對當前shell有效,其他使用者和目前使用者的子shell都無法使用。

使用export可以升級為臨時局部的環境變數,只對目前使用者的當前shell和子shell有效,退出指令碼和退出登入後也失效。

如果想要設定永久的且全域的變數,一種方法是將變數的設定語句放入到/etc/profile檔案中,因為每個使用者登入時,都會調用該檔案並執行其中的語句。如果想立即載入此檔案中的配置使得臨時添加的設定立即生效,只需source該檔案即可。

[root@xuexi ~]# source /etc/profile

/etc/profile檔案是bash的全域設定檔,還有每個使用者的設定檔~/.bash_profile,此檔案中的變數將只對對應的使用者生效。

此外,還有幾個配置bash環境設定檔,具體的見bash環境配置流程。

1.4.4 擷取變數的長度

在使用${}方式引用變數時,變數名前加上#就可以查看該變數的字元長度。空格也算入長度。例如:

[root@xuexi ~]# echo ${#str}12[root@xuexi ~]# echo ${#PATH}92

1.4.5 declare聲明變數

declare [+/-][選項] 變數名

選項說明:

-/+:給變數設定類型屬性,取消給變數設定的類型屬性

-i:聲明為整型

-x:聲明為環境變數

-p:顯式指定變數被聲明的類型

例如,聲明一個環境變數declare -x str,取消該變數declare +x str。

1.4.6 位置變數和特殊變數

$?:上一條代碼執行的回傳指令,回傳0表示標準輸出,即正確執行,否則為標準錯誤輸出。

$$:表示當前登入的shell的PID。

$!:後台啟動並執行最後一個進程PID。

$#:統計參數的個數。

$@:所有單個參數,如"a""b""c""d"。

$*:所有參數的整體,如“abcd”。

$0:指令碼名。

$1……$n:參數位置。

使用下面的指令碼來驗證位置變數和特殊變數。

root@xuexi tmp]# vim var.sh#!/bin/bash# 測試各種變數的作用,包括預定義和自訂變數echo '$?:'$?echo '$$:'$$echo '$!:'$!echo '$#:'$#echo '$@:'$@echo '$*:'$*echo '$0:'$0echo '$1:'$1echo '$2:'$2echo '$3:'$3echo '$4:'$4

使用5個參數來運行該指令碼。

[root@xuexi tmp]# sh ./var.sh a b c d e$?:0$$:6089$!:$#:5$@:a b c d e$*:a b c d e$0:./var.sh$1:a$2:b$3:c$4:d

1.4.7 shift輪替變數

使用shift [N]可以指定參數輪替,每執行一次shift N就踢掉N個參數,預設N為1。

例如在指令碼中:

echo $1   # # 輸出第一個參數值shift 2   # # 踢掉前兩個參數,第三個參數變成$1echo $1   # # 此時$1的值為第三個參數的值shift     # # 又踢掉一個參數,第四個參數變成$1echo $1   # # 輸出第四個參數

1.4.8 shell其他基礎

1、變數中字元的長度:${#VARNAME}

2、變數賦值等:

${parameter:-word}:如果parameter為空白或未定義,則變數展開為“word”;否則展開為parameter的值;

${parameter-word}:和${parameter:-word}幾乎等價,除了parameter設定了但為空白時,變數的結果將是null,而非word。在/etc/init.d/httpd中有此用法。

${parameter:+word}:如果parameter為空白或未定義,不做任何操作,即仍然為空白;否則展開為“word”值;

${parameter:=word}:如果parameter為空白或未定義,則變數展開為“word”,否則為parameter自身;

${parameter:offset}:取子串,從offset處的後一個字元開始取到最後一個字元;

${parameter:offset:length}:取子串,從offset處的後一個字元開始,取lenth長的子串;

其中${parameter:-word}最常用,最後兩個是截取字串的,偶爾也會用到。

3、指令碼設定檔

設定檔中的變數值可以在指令碼中被使用

要在指令碼中調用設定檔,直接使用source config_file或“.  config_file”

服務啟動指令碼支援設定檔:/etc/sysconfig/服務指令碼同名的設定檔

4、局部變數,在函數中定義局部變數使其不影響函數外的同名變數

local VAR_NAME=

5、命令mktemp建立臨時檔案或目錄

mktemp [-d] /tmp/file.XX # X指定越多,隨機產生的尾碼就越長,其中-d表示建立臨時目錄。

例如:

[root@xuexi ~]# mktemp haha.XXXhaha.oOe[root@xuexi ~]# mktemp -d haha.XXXhaha.npz[root@xuexi ~]# touch haha.npz/A.txt

1.4.9 變數的切分、提取和替換

其實是對變數實現的功能,只是使用檔案名稱的說法比較典型,且容易理解它的用途。

例如,將檔案名稱“Linux.docx.jpg”存放到變數file_name中,然後執行從左向右或從右向左的刪除或貪婪刪除。

[root@xuexi tmp]# file_name="Linux.docx.jpg"[root@xuexi tmp]# file_name_greedy=${file_name%%.*}[root@xuexi tmp]# file_name_nongreedy=${file_name%.*}[root@xuexi tmp]# extention_name_greedy=${file_name##*.}[root@xuexi tmp]# extention_name_nongreedy=${file_name#*.}[root@xuexi tmp]# echo -e "${file_name_greedy}\n${file_name_nongreedy}\n${extention_name_greedy}\n${extention_name_nongreedy}"LinuxLinux.docxjpgdocx.jpg

${var%%.*}和${var%.*}中的“%%.*”表示從右向左匹配“.*”並刪除,由於Linux.docx.jpg有兩種合格匹配:“.jpg”和“.docx.jpg”,所以使用兩個%%表示貪婪刪除,即刪除最長相符“.docx.jpg”。可以使用一個%表示非貪婪刪除,表示刪除最短的匹配即“.jpg”。

${var##*.}和${var#*.}中的“##*.”表示從左向右匹配“*.”並執行貪婪刪除,即刪除“Linux.docx.”,同理“#*.”表示非貪婪刪除,即刪除“Linux.”。

除了刪除,還可以實現提取和替換的功能。

[root@xuexi tmp]# echo "${file_name:0:5}"   # 提取第0個位元組後的5個位元組,即1-5位元組Linux[root@xuexi tmp]# echo "${file_name:6:4}"   # 提取第6個位元組後的4個位元組,即第7、8、9、10位元組docx[root@xuexi tmp]# echo "${file_name/jpg/pdf}"   # 非貪婪替換jpg為pdf,即只替換從左向右的第一個Linux.docx.pdf[root@xuexi tmp]# echo "${file_name//jpg/pdf}"  # 貪婪替換jpg為pdf,即所有的jpg都替換為pdfLinux.docx.pdf

不錯的功能是替換。有時候想要刪除PATH環境變數中的某個路徑,可以使用變數替換的功能,似乎沒法使用變數切分來實現。例如:

[root@toystory php]# echo $A/usr/lib64/qt-3.3/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin:/usr/local/apache/bin:/usr/local/mysql:/usr/local/apache/bin

注意,由於可能多次讀取了設定檔,導致PATH中出現了重複的路徑。現在想刪除其中一個路徑。使用下面的命令就可以實現路徑刪除,注意其中使用了轉義符號,並且變數替換的替換值留空了表示刪除前面匹配的部分。

[root@toystory php]# B=${A/:\/usr\/local\/apache\/bin/}[root@toystory php]# echo $B/usr/lib64/qt-3.3/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin:/usr/local/mysql:/usr/local/apache/bin

 

回到系列文章大綱:http://www.cnblogs.com/f-ck-need-u/p/7048359.html

轉載請註明出處:http://www.cnblogs.com/f-ck-need-u/p/7113610.html

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.