【网络运维】Shell:变量进阶知识
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