Shell 變量進階知識
Shell 中的特殊變量
位置參數變量
Shell 腳本中常用的位置參數變量如下:
$0
:獲取當前執行的 Shell 腳本文件名(包含路徑時包括路徑)$n
:獲取第 n 個參數值(n>9 時需使用${n}
)$#
:獲取參數個數$*
:獲取所有參數(加雙引號時視為單個字符串)$@
:獲取所有參數(加雙引號時保留各參數獨立性)
示例:
#!/bin/bash
echo "腳本名稱: $0"
echo "第一個參數: $1"
echo "第二個參數: $2"
echo "第十個參數: ${10}"
echo "參數個數: $#"
echo "所有參數: $*"
echo "所有參數: $@"
echo "帶引號的參數: $@"
執行結果:
$ bash showargs.sh {a..z}
腳本名稱: showargs.sh
第一個參數: a
第二個參數: b
第十個參數: j
參數個數: 26
所有參數: 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
所有參數: 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
帶引號的參數: 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
進程狀態變量
$?
:獲取上一條命令的退出狀態(0 表示成功,非零表示失敗)$$
:獲取當前 Shell 進程的 PID$!
:獲取上一個后臺進程的 PID$_
:獲取上一個命令的最后一個參數
示例:
$ ls /root
ls: 無法打開目錄/root: 權限不夠
$ echo $?
2$ echo $$
2447$ md5sum /dev/zero &
[1] 2611
$ echo $!
2611$ ls /etc/hosts /etc/fstab
$ cat $_
# 顯示 /etc/fstab 內容
Shell 內置變量命令
echo 命令
echo 命令常用選項:
-n
:不換行輸出-e
:解析轉義字符
轉義字符:
\n
:換行\t
:制表符\b
:退格
示例:
$ echo -n "Hello "; echo "World"
Hello World$ echo -e "Line1\nLine2"
Line1
Line2$ echo -e "Name\tAge"
Name Age$ echo -e "123\b456"
12456
eval 命令
eval 命令會將參數組合成新命令并執行:
示例:
$ cat noeval.sh
echo \$$#
$ bash noeval.sh hello world
$2$ cat eval.sh
eval "echo \$$#"
$ bash eval.sh hello world
world
read 命令
從標準輸入讀取數據:
示例:
#!/bin/bash
read -p "請輸入內容: " input
echo "您輸入的內容是: $input"# 隱藏輸入內容(適用于密碼)
read -s -p "請輸入密碼: " password
echo
echo "密碼已接收"
exec 命令
exec 命令會替換當前進程執行指定命令:
示例:
# 執行 sleep 命令替換當前 shell
$ exec sleep 10
# 10 秒后返回原 shell# 從文件讀取內容
$ cat exec.sh
#!/bin/bash
seq 5 > /tmp/seq.log
exec < /tmp/seq.log
while read line
doecho $line
done
shift 命令
shift 命令用于移動位置參數:
示例:
$ cat shift.sh
#!/bin/bash
echo "第一個參數: $1"
shift
echo "shift 后的第一個參數: $1"$ bash shift.sh A B C
第一個參數: A
shift 后的第一個參數: B
Shell 變量子串處理
常用子串操作
${parameter}
:返回變量值${#parameter}
:返回變量長度${parameter:offset}
:從指定位置提取子串${parameter:offset:length}
:提取指定長度子串${parameter#word}
:從開頭刪除最短匹配${parameter##word}
:從開頭刪除最長匹配${parameter%word}
:從結尾刪除最短匹配${parameter%%word}
:從結尾刪除最長匹配${parameter/pattern/string}
:替換第一個匹配${parameter//pattern/string}
:替換所有匹配
使用示例
$ str="abc123abc123"# 獲取長度
$ echo ${#str}
12# 提取子串
$ echo ${str:3}
123abc123
$ echo ${str:3:4}
123a# 刪除子串
$ echo ${str#a*c}
123abc123
$ echo ${str##a*c}
123# 替換子串
$ echo ${str/abc/def}
def123abc123
$ echo ${str//abc/def}
def123def123
實際應用案例
重命名文件:
[furongwang@shell ~]$ touch stu-202112-snap.jpg# 創建sh腳本文件
$ file="stu-202112-snap.jpg"
$ mv $file ${file/2021/2025} # 改為 2025
$ mv $file ${file/-snap/} # 刪除 -snap
Shell 特殊擴展變量
常用擴展變量
${parameter:-word}
:變量為空時返回 word${parameter:=word}
:變量為空時設置并返回 word${parameter:?word}
:變量為空時輸出錯誤信息${parameter:+word}
:變量不為空時返回 word
使用示例
# 變量未定義
$ unset test
$ echo ${test:-DEFAULT}
DEFAULT# 變量定義
$ test=hello
$ echo ${test:-DEFAULT}
hello# 設置默認值
$ echo ${SHELL:=/bin/bash}
/bin/bash# 錯誤檢查
$ unset test
$ echo ${test:?變量未定義}
-bash: test: 變量未定義
實際應用案例
Apache 啟動腳本片段:
HTTPD_LANG=${HTTPD_LANG:-"C"}
httpd=${HTTPD:-/usr/sbin/httpd}
pidfile=${PIDFILE:-/var/run/httpd.pid}
安全刪除文件:
#!/bin/bash
# 防止 path 變量未定義
find ${path:-/tmp} -name "*.tar.gz" -type f -mtime +7 | xargs rm -f