; 分號
使用分號可以在一行使用多個命令
[root@localhost ~]# touch a.txt;ls anaconda-ks.cfg a.txt initial-setup-ks.cfg
;; 雙分號
專用於case,每個條件塊以;;結束
[root@localhost shell]# cat ex_case.sh #!/bin/bash case "$1" in cat) echo 'is a cat.' echo 'end' ;; dog) echo is a dog.;; *) echo "bash $0 dog|cat" ;; esac [root@localhost shell]# bash ex_case.sh dog is a dog.
. 點號(dot)
點號在不同場景有着不同的含義,在目錄路徑中,一個點代表當前工作目錄,兩個點代表父目錄;當一個文件以點號開頭,表示一個隱藏文件;在正則表達式,點號代表匹配單個字符;
點號可以用於執行某個文件,同樣,在腳本中,用於導入文件,等於source指令。
[root@localhost shell]# cat a.txt name=david [root@localhost shell]# cat a.sh #!/bin/bash # 這里的‘點號’等於 source,表示引入a.txt,類似python的import導入一個模塊文件 . a.txt echo $name [root@localhost shell]# . a.sh david
'' 單引號和 "" 雙引號
引號代表字符串,單引號不能解釋$符號,不能變量轉換。
[root@localhost shell]# name=tom [root@localhost shell]# echo '$name' $name [root@localhost shell]# echo "$name" tom
`` 反引號
相當於$()表示命令替換,將執行命令結果傳給變量參數
[root@localhost shell]# td=`date +%F` [root@localhost shell]# echo today $td today 2020-10-16
: 冒號
表示零命令,返回True,也用於函數等,作為占位符
[root@localhost shell]# : [root@localhost shell]# echo $? 0 [root@localhost shell]# cat /dev/null > a.txt [root@localhost shell]# : > a.txt # 寫法更簡短,等於上面
! 感嘆號
用於否定
? 問號
正則表達式中,表示匹配任一字符;也用於三元運算中
三元運算符語法是“條件表達式?表達式1:表達式2”,使用這個算法可以使調用數據時逐級篩選。
[root@localhost shell]# ls a.sh a.txt ex_case.sh [root@localhost shell]# ls ?.sh a.sh [root@localhost shell]# cat a.sh #!/bin/bash a=100 (( t = a<45?7:11 )) # 三元運算 # ^ ^ ^ # If a < 45, then t = 7, else t = 11." # a=100 echo "t = $t " [root@localhost shell]# bash a.sh t = 11
$ 變量符號,正則表達式表示行尾
${} 變量的正則表達式
${parameter},等於$parameter,即是變量參數的值,可用於變量和字符串連接起來
[root@localhost shell]# cat a1.sh #!/bin/bash your_id=${USER}-on-${HOSTNAME} echo "$your_id" echo "Old \$PATH = $PATH" export PATH=${PATH}:/opt/bin # Add /opt/bin to $PATH echo "New \$PATH = $PATH" [root@localhost shell]# bash a1.sh root-on-localhost.localdomain Old $PATH = /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin New $PATH = /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin:/opt/bin
${parameter-default}, ${parameter:-default}
如果參數未定義,則使用default,這兩個幾乎是一樣的,平時使用${parameter-default}更簡短
[root@localhost shell]# cat a2.sh #!/bin/bash var1=1 var2=2 echo ${var1-$var2} # 1 echo ${var3-$var2} # 2 echo ${username-`whoami`} # exe whoami username0= echo "username0 = ${username0-`whoami`}" # exe username0 [root@localhost shell]# bash a2.sh 1 2 root username0 =
${parameter=default}, ${parameter:=default}
如果parameter未定義,則設置值為default
[root@localhost shell]# echo ${var=abc} abc [root@localhost shell]# echo ${var=xyz} # 因為var的值已經定義 abc
$*, $@ 所有定位參數
$*和 $@要加引號,符號 $* 將所有的引用變量視為一個整體。但符號 $@ 則仍舊保留每個引用變量的區段觀念。
當$*沒有加雙引號,效果和$@效果是一樣的。
[root@localhost shell]# cat argslist2.sh #!/bin/bash if [ ! -n "$1" ] then echo "usage:`basename $0` arg1 arg2..." exit 1 fi index=1 echo "Listing args with \"\$*\":" # $* 將所有位置參數當做整體一個單詞 for arg in "$*" do echo "args #$index=$arg" let "index+=1" done index=1 echo "Listing args with \"\$*\"(unquoted):" # $* 將所有位置參數當做獨立的單詞 for arg in $* do echo "args #$index=$arg" let "index+=1" done index=1 echo "Listing args with \"\$@\":" # $@ 將所有位置參數當做獨立的單詞 for arg in "$@" do echo "args #$index=$arg" let "index+=1" done index=1 echo "Listing args with \"\$@\"(unquoted):" # $@ 將所有位置參數當做獨立的單詞 for arg in $@ do echo "args #$index=$arg" let "index+=1" done [root@localhost shell]# bash argslist2.sh one two three Listing args with "$*": args #1=one two three Listing args with "$*"(unquoted): args #1=one args #2=two args #3=three Listing args with "$@": args #1=one args #2=two args #3=three Listing args with "$@"(unquoted): args #1=one args #2=two args #3=three
$# 位置參數的總數量
1)命令組
括號內的命令列表啟動一個子shell
2)數組初始化
用來表示數組
[root@localhost shell]# ( list=(1 3 5 7); for i in ${list[*]}; do echo $i; done ) 1 3 5 7
{xxx,yyy,zzz,...} 內容擴展
[root@localhost shell]# cp /data/shell/{file2,file3,a.txt} /tmp
{a..z} 具有順序性質的內容擴展
[root@localhost shell]# echo {1..9} 1 2 3 4 5 6 7 8 9 [root@localhost shell]# 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
[ ] 和 [[ ]] 中括號和雙中括號
#!/bin/bash file=/etc/passwd # use [] is also valid if [[ -e $file ]] then echo "passwd file exists." fi # if use [] will report an error. if [[ -e $file && -e /etc/hosts ]] then echo "both file exists." else echo "no exists." fi
$[ ... ] 計算整數之和,同$((...))
[root@localhost ~]# echo $[5+3] 8 [root@localhost ~]# echo $[5+3] 8 [root@localhost ~]# echo $((5+3)) 8
\<...\> 定位符號
\<the\> 在二則表達式中,用於匹配單詞邊界,比如只匹配‘the’,不匹配‘them’、‘there’等
[root@localhost shell]# cat textfile This is line 1, of which there is only one instance. This is the only instance of line 2. This is line 3, another line. This is line 4. [root@localhost shell]# grep '\<the\>' textfile This is the only instance of line 2.
& 后台運行
- 破折號
重定向stdin或stdout
[root@localhost shell]# cat - david david tom tom … Ctrl-D
正如例子所示,鍵盤stdin什么內容就會stdout什么內容
破折號使用場景一:
通過tar打包和解包方式,復制目錄下的內容到別的地方,等於cp -a /tmp/* /mnt
(cd /tmp && tar cf - . ) | (cd /mnt && tar xpvf -)
破折號使用場景二:
#!/bin/bash # Set date in backup filename. BACKUPFILE=backup-$(date +%F) # If no BACKUPFILE variable,it will default to 'backup.tar.gz'. archive=${BACKUPFILE-backup} # Backup of all files changed in last day. tar cvf - `find . -mtime -1 -type f -print` > $archive.tar # ---------------------------------------------------------------- # Another way: # find . -mtime -1 -type f -print | xargs tar cvf $archive.tar # find /etc -mtime -1 -type f -exec tar cvf $archive.tar {} \; echo "Directory $PWD backed up in archive file \"$archive.tar\"." exit 0 [root@localhost shell]# bash backupfile.sh ./textfile ./backgroup.sh ./filetext ./test.tar.bz2 ./tmp.tar.gz2 ./test.sh ./backupfile.sh Directory /data/shell backed up in archive file "backup-2020-10-18.tar".
IFS(internal filed separator) 內部字符分隔符
IFS環境變量定義了bash shell 用作字段分隔符的一系列字符。默認會將下列字符當做字符分隔符:
# 默認會將下列字符當做字符分隔符:空格、制表符、換行符 [root@localhost shell]# set | grep IFS IFS=$' \t\n'
如果需要使用其它分隔符,那需要臨時修改IFS環境變量:
#!/bin/bash # find files in the PATH IFS=: for folder in $PATH do echo $folder for file in $folder/* do if [ -x $file ] then echo " $file" fi done done