shell 里面的奇葩字符實(shí)現(xiàn)
在我接觸過的編程語言里面,最奇葩的兩個(gè)就屬 JavaScript 和 Shell 了。因?yàn)樗鼈冇兄嗟恼Z法糖跟特殊字符,總是能夠讓你措手不及,并且編程習(xí)慣也跟Java 和 Python 等語言大相徑庭??傊f不要因?yàn)樗鼈兪悄_本語言就輕視它們,否則你就會(huì)被打得暈頭轉(zhuǎn)向。
這兩個(gè)奇葩之間比起來呢,Shell 的奇葩之處在于特殊符號多,騷操作也多。比如你以為 . 這是個(gè)點(diǎn),其實(shí)它代表的意思遠(yuǎn)不止一個(gè)點(diǎn)那么簡單 。
下面的內(nèi)容是我根據(jù)網(wǎng)上資料及平時(shí)使用經(jīng)驗(yàn)整理的一份Shell 中的特殊字符。如果大家覺得有用的話就點(diǎn)贊收藏吧。
; 單分號,一般作為命令分隔符??梢詫蓚€(gè)命令放在同一行。如: echo hello; echo there,但真正寫腳本的時(shí)候盡量不要這樣寫。
;; 雙分號,用在 case條件語句的結(jié)束符。如:
case "$variable" in abc) echo "\$variable = abc" ;; xyz) echo "\$variable = xyz" ;; esac
% 百分號,用于表示取余操作,也用于正則表達(dá)式。
~ 波浪線,表示家目錄,等價(jià)于$HOME。如 cd ~
~+ 表示當(dāng)前工作目錄,等價(jià)于$PWD。
~- 表示上一個(gè)工作目錄,等價(jià)于 ..。
| 管道標(biāo)識符,將上一個(gè)命令的輸出作為下一個(gè)命令的輸入,經(jīng)常用到,沒什么好說的。
>| 強(qiáng)制重定向。強(qiáng)制重寫已經(jīng)存在的文件。
|| 表示邏輯或操作。
& 讓命令在后臺(tái)運(yùn)行,例如 command & 一般用于啟動(dòng)后臺(tái)進(jìn)程服務(wù)。
&& 表示邏輯與操作。
* 星號,主要用于通配符匹配,當(dāng)然也用于乘法表達(dá)式。
\ 主要用于轉(zhuǎn)義特殊字符,比如想轉(zhuǎn)義雙引號,可以這樣 echo \" 輸出 “。
/ 文件路徑分隔符,比如 /opt/app/projects/ 。當(dāng)然也用作除法表達(dá)式。
. 點(diǎn)號,這個(gè)符號作用比較多。 首先可以等價(jià)于 source 命令。也可以作為文件名字,在文件名開頭,表示該文件是個(gè)隱藏文件。 還可以表示當(dāng)前目錄, 比如拷貝某個(gè)文件到當(dāng)前目錄 cp /opt/app/a.md . 。如果是兩個(gè)連續(xù)的點(diǎn)則表示上一級目錄,比如 cd ..。
最后,點(diǎn)號也是正則表達(dá)式的元字符。
" 雙引號,雙引號里面的變量一般會(huì)被解析成賦值的內(nèi)容。比如
name=frank echo "hello $name" # hello frank
' 單引號,單引號里面的變量一般不會(huì)被解析,比如
name=frank echo 'hello $name' #hello $name
' 反引號(ESC鍵下面那個(gè)),要跟單引號區(qū)分開。反引號里面的內(nèi)容會(huì)被當(dāng)作指令執(zhí)行,并將執(zhí)行的結(jié)果賦值給變量。比如:
file=`ls ~` echo $file #家目錄下所有文件。
! 感嘆號,一般用于取反。比如 != 表示不等。騷操作在終端中執(zhí)行,可以表示歷史指令比如 !-3,將會(huì)輸出你剛剛輸入的指令。但在腳本中不支持該種寫法。
** 雙星號,算術(shù)運(yùn)算中表示求冪運(yùn)算。比如
let "a=3**2" echo $a #9
? 問號,表示條件測試;也用作三元運(yùn)算符。也是正則表達(dá)式元字符。
$ 美元符,放到變量前面,即引用一個(gè)變量的內(nèi)容,比如:echo $PATH;當(dāng)然也是正則表達(dá)式的元字符。
${} 參數(shù)替換。用于在字符串中表示變量值。比如
name=frank echo "hello ${name}" #hello frank
$*,$@ 這兩個(gè)特殊字符都用于獲取傳遞給腳本的所有參數(shù)。當(dāng)他們被雙引號包圍時(shí),"$*"會(huì)將所有的參數(shù)從整體上看做一份數(shù)據(jù)。而"$@"仍然將每個(gè)參數(shù)都看作一份數(shù)據(jù),彼此之間是獨(dú)立的。
$# 表示參數(shù)個(gè)數(shù)。
$? 返回最近的一個(gè)命令或腳本的退出狀態(tài)碼,正確執(zhí)行則返回0,否則返回非0。
$$ 雙美元符, 返回當(dāng)前腳本的進(jìn)程號。
() 小括號,命令組,一組圓括號括起來的命令代表一個(gè)命令組,以子shell方式運(yùn)行。同時(shí)小括號里面的的變量類似局部變量,外部不能訪問。比如
a=123 ( a=321; ) echo "a = $a" # a = 123
還可以用于數(shù)組初始化。例如
arr=(ele1 ele2 ele3) echo ${arr[1]} # ele2
{xxx,yyy,zzz} 有人叫花括號擴(kuò)展,我舉幾個(gè)例子,可能大家就明白了。注意不能有空格。
echo {a,b,c}-{d,e,f} # a-d a-e a-f b-d b-e b-f c-d c-e c-f cat {file1,file2,file3} > merge_file #將三個(gè)file的內(nèi)容一同輸入merge_file cp file.{txt,backup} #拷貝file.txt成file.backup
{a..z} 跟上面類似,還是看例子吧。
echo {a..z} # a b c d e f g h i j k l m n o p q r s t u v w x y z echo {0..3} # 0 1 2 3
{} 花括號,表示代碼塊 ,也用于表示匿名函數(shù)。也可以結(jié)合重定向符使用。例如:
fileline=~/a.txt { read line1 read line2 } < $fileline echo $line1 echo $lien2
會(huì)將a.txt的前兩行內(nèi)容賦值給變量line1和line2;
騷操作在xargs -i中,還可以作為文本的占位符,用來標(biāo)記輸出文本的位置。
比如 ls *.txt | xargs -i -t cp {} {}.bak 會(huì)把所有txt文件拷貝一份,命名成txt.bak
{} \; 表示路徑名字。一般跟find命令一起使用。例如 find . -name "*.sh" -exec rm {} \;找出所有sh腳本,然后刪除。注意{} 和 \ 之間的空格,分號必須存在。
[] 中括號,用于在里面寫判斷表達(dá)式。也可以當(dāng)作數(shù)組用。當(dāng)然也是正則表達(dá)式元字符。
[[]] 雙中括號,也用于在里面寫判斷表達(dá)式,比上面但中括號更靈活。
$[] 計(jì)算整數(shù)表達(dá)式,已經(jīng)不推薦使用。例如
a=3; b=7; echo $[$a+$b] # 10
(()) 雙小括號, 計(jì)算整數(shù)表達(dá)式,推薦使用。如
a = 23 (( a++ )) echo "a (after a++) = $a" # 24
> ,&>, >&, >> 這四個(gè)都是重定向符,分別舉例說明。
cat ~/a.txt >a.log 將文件a.txt的內(nèi)容輸出到文件a.log中去,如果文件存在則覆蓋;
command &>filename 重定向command的標(biāo)準(zhǔn)輸出(stdout)和標(biāo)準(zhǔn)錯(cuò)誤(stderr)到文件filename中,一般用于啟動(dòng)進(jìn)程腳本;
command >&2 把command的標(biāo)準(zhǔn)輸出(stdout)重定向到標(biāo)準(zhǔn)錯(cuò)誤(stderr)中;
cat ~/a.txt >> a.log 把a(bǔ).txt的輸出以追加得方式輸入到文件a.log中,如果文件不存在則創(chuàng)建。
- 短橫線,可用于參數(shù)選擇 例如 ls -al。 也可以表示上一個(gè)工作目錄,例如 cd -。當(dāng)然也是數(shù)學(xué)運(yùn)算符,用于表示減法操作。
= 等號,數(shù)學(xué)運(yùn)算符,賦值操作。 例如
a=28 echo $a
也可以用于表示比較操作,例如,if [ "$a" = "$b" ] 注意等號左右兩側(cè)要有空格。
# 井號,一般用于注釋語句前面,表示該條語句是注釋。也是正則表達(dá)式的元字符。
注意:
腳本的第一行#!/bin/bash 不作為注釋,在雙引號或者單引號以及轉(zhuǎn)義字符之后的也不會(huì)作為注釋符使用。例如
echo "The # here does not begin a comment." echo 'The # here does not begin a comment.' echo The \# here does not begin a comment.
騷操作 可以做進(jìn)制轉(zhuǎn)換,例如
echo $((2#101)) #5 echo $((8#101)) #65 echo $((10#101)) #101
, 逗號,用于連接一連串的數(shù)學(xué)表達(dá)式,這串?dāng)?shù)學(xué)表達(dá)式均被求值,但只有最后一個(gè)求值結(jié)果被返回。例如:
# Set "a = 9" and "t2 = 15 / 3" let "t2 = ((a = 9, 15 / 3))"
也可以用于連接字符串,比如 echo {a,b}/test 輸出 a/test b/test
騷操作 用在變量引用中,表示首字母小寫,如果是兩個(gè)逗號,則表示全部小寫。例如
a="AFrank" echo ${a,} #aFrank echo ${a,,} #afrank
+ 數(shù)學(xué)運(yùn)算符,表示加操作。也是正則表達(dá)式元字符。
騷操作 用于設(shè)置變量值。使用方式 ${parameter+alt_value} 如果變量 parameter 設(shè)置了值,則使用 alt_value 的值,否則使用空字符。
舉個(gè)例子,感受一下
#param1 not set a=${param1+xyz} echo "a = $a" # a = #parma2 set null param2= a=${param2+xyz} echo "a = $a" # a = xyz param3=123 a=${param3+xyz} echo "a = $a" # a = xyz
注意 配合冒號使用時(shí)會(huì)有不同。舉個(gè)例子,繼續(xù)感受一下
a=${param4:+xyz} echo "a = $a" # a = param5= a=${param5:+xyz} echo "a = $a" # a = #Different result from a=${param5+xyz} param6=123 a=${param6:+xyz} echo "a = $a" # a = xyz
^ 用于正則表達(dá)式。
騷操作 用于大小寫轉(zhuǎn)化。看下面的例子。
var=hellFrank echo ${var^} # HelloFrank echo ${var^^} # HELLOFRANK
<< 雙小于號,稱作 here-doc。一般用于給命令提供輸入多行內(nèi)容。比如
tr a-z A-Z <<EOF > one > two > three > EOF
輸出:
ONE TWO THREE
默認(rèn)的,here doc里面的變量會(huì)進(jìn)行替換。比如
cat << EOF > Working dir $PWD > EOF
輸出:Working dir /home/frank
如果給here doc 標(biāo)識符加上雙引號或者單引號則會(huì)禁止變量替換。比如
cat << "EOF" > Working dir $PWD > EOF
輸出:Working dir $PWD
騷操作
再 <<后面添加-,可以忽略TAB空白字符。比如
tr a-z A-Z <<-EOF > one > two > three > EOF
輸出:ONE TWO THREE
<<< 三個(gè)小于號,稱作here string,here doc的變種。比here doc更靈活。例如 tr a-z A-Z <<<"Yes it is a string" # YES IT IS A STRING name=frank # 雙引號里面會(huì)解析變量 tr a-z A-Z <<<"Yes i'm $name" # YES I'M FRANK # 單引號里面不解析變量 tr a-z A-Z <<<'Yes i\'m $name' # YES I'M $NAME
: 冒號,表示空,什么都不做,但是有返回值,返回值為0(即true)
例如:: ; echo $? 輸出0。 $? 的意思就是返回上條指令的狀態(tài)。
利用此特性可以作為 while 的無限循環(huán)條件,也可以作為 if 分支的占位符。
比如
while : #same as while true do operation-1 operation-2 ... operation-n done
或者
if condition then : # Do nothing and branch ahead else # Or else ... take-some-action fi
除此之外還可以結(jié)合重定向符號使用,將文件內(nèi)容清空,但是不改變文件權(quán)限,如果不存在則會(huì)自動(dòng)創(chuàng)建。
: > data.xxx # File "data.xxx" now empty.
等價(jià)于 cat /dev/null >data.xxx 如果以追加方式的重定向,則對文件不構(gòu)成任何修改。同樣如果文件不存在也會(huì)新建一個(gè)。例如 : >> data.xxx 。
注意 這個(gè)只能在普通文件中使用,不能在管道,符號鏈接和其他特殊文件中使用;
你也可以作為域分隔符,比如環(huán)境變量$PATH中,或者passwd中,都有冒號的作為域分隔符的存在;例如
usr/local/bin:/bin:/usr/bin:/sbin:/usr/sbin:/usr/games
騷操作 設(shè)置默認(rèn)值,如果param沒有設(shè)置,則使用默認(rèn)值,例如
parma=frank echo ${param:=default} #frank echo ${test:=default} #default
你也可以將冒號作為函數(shù)名,不過這個(gè)會(huì)將冒號的本來意義轉(zhuǎn)變,所以不要這么搞。
:() { echo "The name of this function is colon" }
以上內(nèi)容來源參考:(http://tldp.org/LDP/abs/html/special-chars.html),希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- Shell腳本8種字符串截取方法總結(jié)
- Shell字符串比較相等、不相等方法小結(jié)
- Shell字符串截取的詳細(xì)方法
- Shell腳本中計(jì)算字符串長度的5種方法
- 用Shell判斷字符串包含關(guān)系的方法小結(jié)
- Shell腳本實(shí)現(xiàn)簡單分割字符串
- 在Shell中分割字符串的例子
- Shell中判斷字符串是否為數(shù)字的6種方法分享
- Shell獲取字符串長度的多種方法總結(jié)
- Shell命令行中特殊字符與其轉(zhuǎn)義詳解(去除特殊含義)
- shell 字符串操作(長度,查找,替換)詳解
- Shell腳本實(shí)現(xiàn)查找字符串中某字符最后出現(xiàn)的位置
相關(guān)文章
shell腳本函數(shù):控制顏色、定位、居中顯示的代碼
這篇文章主要介紹了shell腳本函數(shù):控制顏色、定位、居中顯示的代碼,需要的朋友可以參考下2014-04-04一天一個(gè)shell命令 linux文本操作系列-diff命令詳解
這篇文章主要介紹了一天一個(gè)shell命令 linux文本操作系列-diff命令詳解,需要的朋友可以參考下2016-06-06Shell腳本實(shí)現(xiàn)隨機(jī)數(shù)多種方法介紹(date、random、uuid)
這篇文章主要介紹了Shell腳本實(shí)現(xiàn)隨機(jī)數(shù)多種方法介紹,本文講解了通過時(shí)間獲得隨機(jī)數(shù)、通過內(nèi)部系統(tǒng)變量、通過系統(tǒng)內(nèi)部唯一數(shù)據(jù)生成隨機(jī)數(shù)等方法,需要的朋友可以參考下2014-11-11Shell執(zhí)行/調(diào)用Java/Jar程序例子的實(shí)例詳解
這篇文章主要介紹了Shell執(zhí)行/調(diào)用Java/Jar程序例子的實(shí)例詳解的相關(guān)資料,這里提供實(shí)例幫助大家實(shí)現(xiàn)這樣的功能,需要的朋友可以參考下2017-08-08