TypechoJoeTheme

MetMan's Blog

网站页面

Shell变量(二)

MetMan博 主
2024-02-16
/
0 评论
/
152 阅读
/
1488 个字
/
百度已收录
02/16
本文最后更新于 2024年02月16日,已超过 216天没有更新。如果文章内容或图片资源失效,请留言反馈,我会及时处理,谢谢!

参数展开

参数展开(parameter expansion)是shell提供变量值在脚本程序中使用的过程。缺省情况,未定义的变量会展开成null(空的)字符串。

有两种方式引用变量值:

  • $var
  • ${var}

注:不要和命令替换操作$()搞混。

展开运算符

分为替换运算符模式匹配运算符

  • 替换运算符

替换运算符用于测试变量是否存在,且在某种情况下允许默认值(缺省值)的替换。比如,
当脚本需要根据用户输入位置参数来决定脚本执行行为时,为了防止用户执行时忘了在命令行上输入参数导致脚本运行出错,可以使用替换运算符得到一个缺省值备用。

运算符替换用途
${varname:-value}如果varname存在且非null,则返回其值;否则,返回value如果变量未定义,返回默认值
${varname:=value}如果varname存在且非null,则返回varname的值;否则,设置varname值为value,并返回其值如果变量未定义,则设置变量为默认值
${varname:?message}如果varname存在且非null,则返回它的值;否则,显示varname:message,并退出当前的命令或脚本为了捕捉由于变量未定义所导致的错误
${varname:+value}如果varname存在且非null,则返回value;否则,返回null测试变量的存在

注1:以上每个运算符内冒号(:)都是可选的,如果省略冒号,则将每个定义中的“存在且非null”部分改为“存在”,即运算符仅用于测试变量是否存在,不测试其是否有值。

注2:varname前不需要加$符号。

示例:

var=${count:-0}  
echo $count   # null ,由于count未定义,只返回默认值,但不对count赋值,所以仍为null
echo $var     # 0,由于count未定义,默认返回0值,所以var值为0

var1=${count1:=0}
echo $count1    # 0,由于count1未定义,设置它值为缺省值,并将该值返回
echo $var1      #0,count1未定义,返回该值

${count2:?"undefined"}     # count: undefined

count4=3
var2=${count4:+0}   # 0,由于count4已定义,返回值0

count5=       #变量只存在,但是null
var3=${count5-0}   # 空值
  • 模式匹配运算符

通常用来分割路径的组成部分,例如目录前缀、文件名后缀等。

运算符替换用途
${variable#pattern}如果模式匹配变量值开头处,则删除匹配的最短部分,并返回剩下的部分...
${variable##pattern}如果模式匹配变量值的开头处,则删除匹配的最长部分,并返回剩下的部分保留basename
${variable%pattern}如果模式匹配变量值的结尾处,则删除匹配的最短部分,并返回剩下的部分去除后缀
${variable%%pattern}如果模式匹配变量值的结尾处,则删除匹配的最长部分,并返回剩下的部分

注:

  • #匹配前面,%匹配后面;单个#%匹配最短部分,两个匹配最长部分(贪婪算法)。
  • 模式/*/匹配任何位于两个斜杠之间的元素,.*匹配点号后面接着的任何元素。

例:

path=/home/user/project/filename.txt
echo ${path#/*/}     # 最短匹配/home/并删除,返回user/project/filename.txt
echo ${path##/*/}    # 最长匹配/*/,返回filename.txt
echo ${path%.*}      # 返回/home/user/project/filename 
echo ${path%%.*}     # 返回/home/user/project/filename 

echo ${path##*.}     # 提取后缀名,返回后缀txt
  • 字符串变量长度

${#variable}返回$variable值里的字符长度。

echo ${#path}   # 返回 31

对于数组变量,·${#array}返回数组第一个元素长度。

  • 子字符串提取和匹配替换
运算符作用
${var:pos}提取变量var的pos位置开始的字符串
${var:pos:len}提取变量var的pos位置开始的字符串,最大长度为len
${var/pattern/replace}var中第一个匹配pattern部分替换为replace
${var//pattern/replace}所有匹配pattern部分替换为replace
${var/#pattern/replace}如果var前缀匹配pattern,匹配部分替换为replace
${var/%pattern/replace}如果var后缀匹配pattern,匹配部分替换为replace
${!varprefix*} ,${!varprefix@}匹配前面以varprefix开始的已声明变量名称

示例:

var=abc123456789def
echo ${var:3}    # 123456789def 从第3个偏移量开始输出
echo ${var:3:9}  # 123456789 
echo ${var/456/xyz} # abc123xyz789def
echo ${var/#abc/000}  # 000123456789def
echo ${var/#123/000}  # abc123456789def  没有前缀匹配,返回原值

filename=abc.txt
echo ${filename/%txt/grd}  # abc.grd   替换后缀名

a=${!file*}   
echo $a   # filename  
b=${!a}   
echo $b   # abc.txt  间接引用

位置参数

位置参数(positional parameter)指shell脚本的命令行参数,也表示shell函数内的函数参数。名称以单个整数命名。$0指脚本名称,$1是第一个参数,依次类推。当参数大于9个时,引用该参数时需要用{}括起来。

值测试与模式替换运算符结合使用:

filename=${1:-/dev/tty}

使用内部变量对传递的参数个数及值得引用:

变量意义
#传递给shell脚本或函数的参数总数
*一次表示所有的命令行参数,置于双引号内,则展开为一单独参数
@一次表示所有的命令行参数,置于双引号内,会展开为个别的参数

例:

$ set -- hello "hi there" greetings #调用set命令但不给任何选项,则设置位置参数的值
$ echo $#
3

$ for i in $*; do echo i is $i; done
i is hello     
i is hi             # 带空格的字符串展开为多个单词
i is there
i is greetings

$ for i in $@; do echo i is $i; done    # 不加双引号,$*与$@效果相同
i is hello    
i is hi    
i is there    
i is greetings

$ for i in "$*"; do echo i is $i; done     #加了双引号,$*表示一个字符串
i is hello hi there greetings              #等同于 "$1 $2 ..."

$ for i in "$@"; do echo i is $i ; done  #加了双引号,$@保留真正的参数
i is hello                             #等同于 "$1" "$2" ...
i is hi there
i is greetings

shift命令用于”截去“来自列表的位置参数,由左开始。一旦执行shift,$1的初始值
永远消失,取而代之的是$2的旧值。$2的值变为$3的旧值,依次类推。同时,$#
减1.

一个常见用法是对参数选项进行处理:

while [ $# != 0 ]
do
    case $1 in
    ...                   #处理第一个参数
    esac
    shift               #移除第一个参数
done

特殊变量(内置变量)

除了上面介绍的特殊变量,脚本还内置了如下变量(不完全列出):

变量意义
?前一命令的退出状态
$shell进程的进程ID,常用于建立唯一性的临时文件名
HOME根(登录)目录
IFS内部字符分隔符,一般设为空格、制表符tab及换行newline
LANG当前locale的默认名称
PATH命令的查找路径
PWD当前工作目录 !

小结

参数展开是引用变量值的过程。除了两种普通的引用变量本身值的方法:$var${var}
对变量还可以使用替换运算符和模式匹配运算符,对变量进行处理得到想要的值。shell内置
了许多变量可以方便调用脚本环境。

熟练掌握参数展开语法,可以方便的处理字符串,包括文件名路径提取、后缀名修改,提取子字符串等等操作。

shellbash
朗读
赞(0)
赞赏
感谢您的支持,我会继续努力哒!
版权属于:

MetMan's Blog

本文链接:

https://blog.metman.top/index.php/archives/91/(转载时请注明本文出处及文章链接)

评论 (0)

互动读者

标签云

最新回复

暂无回复

登录
X
用户名
密码