Shell变量与参数传递

10 篇文章 0 订阅





1、变量的定义与使用


在Shell脚本中,我们可以自由定义变量来存储数据。变量定义的语法如下:

var_name="value"

例如,定义一个变量greeting并给它赋值为Hello

greeting="Hello"

变量的使用只需要在变量名前添加$符号来引用这个变量即可:

echo $greeting            # Hello
echo ${greeting}          # Hello

变量名外面的花括号{}是可选的,{}可以帮助解释器识别变量的边界,例如下面这种情况:

echo "${greeting}Shell"   # HelloShell

如果不给变量greeting添加{},写成echo "$greetingShell",解释器就会把greetingShell当成一个变量,最终导致结果为空

2、变量的命名规范


和其它语言类似,Shell变量的命名须遵循以下规则:

  • 只包含字母、数字和下划线:注意字母大小写敏感,不能以数字开头
  • 避免使用Shell关键字:例如ifthenelsefi
  • 使用大写字母表示常量:习惯上,常量的命名通常使用大写字母
  • 避免使用特殊符号:例如$等,Shell特殊符号会与Shell语法产生冲突
  • 避免使用空格:变量名和等号两侧不能包含空格,空格通常用于分隔命令和参数

3、Shell变量的类型


Shell支持不同类型的变量,其中一些主要的类型包括:

1)字符串变量

在Shell中,变量通常被视为字符串。可以使用单引号'或双引号"来定义字符串,例如:

greeting='Hello'
greeting="Hello"

2)整数变量

在一些Shell中,可以使用declaretypeset命令来声明整数变量,例如:

declare -i my_integer=10

这样的声明告诉Shell将my_integer视为整数,如果将非整数值赋值给它,Shell会尝试将其转换为整数

3)数组变量

Shell允许在一个变量中存储多个值。Shell只支持一维数组,初始化时不需要定义数组大小,例如:

my_array=(A B "C" D)

与其它语言类似,数组元素的下标从0开始,读取数组元素值的一般格式为:

${array_name[index]}

例如,读取第三个元素:

echo "${my_array[2]}"       # C

4、Shell变量的分类


Shell中的变量主要分为系统变量、用户(自定义)变量、位置变量和特殊变量

4.1、系统变量(全局变量)

系统变量(环境变量)是指在Linux系统中提前创建的一类变量,主要用于设置用户的工作环境,包括用户宿主目录、命令查找路径等。环境变量的值由Linux系统自动维护,当用户注销时这些值将丢失

环境变量适用于所有用户进程,一般在/etc/profile文件中定义。一般地,所有环境变量都大写,且必须用export命令导出

1)设置环境变量

编辑配置文件/etc/profile,将Shell变量输出为环境变量(全局变量):

# 方式1
var_name=value; export var_name
# 方式2
var_name=value
export var_name
# 方式3(推荐)
export var_name=value

2)刷新环境变量

刷新配置文件/etc/profile,让修改后的配置信息立即生效:

source /etc/profile

3)查询环境变量

查询环境变量的值,检查环境变量是否生效:

echo $var_name

环境变量其它相关命令如下:

# 查看系统所有环境变量
env
# 清除系统环境变量
unset var_name

4.2、用户变量(局部变量)

用户变量(局部变量)在用户当前Shell生命周期的脚本中使用,其他Shell启动的程序不能访问,不同用户可以定义各自的用户变量

用户变量的定义和使用见本文第1节。声明静态变量(只读变量)的语法如下:

# 设置变量为只读
var_name=value
readonly var_name   

用户变量其它相关命令如下:

# 显示所有用户变量
set
# 清除用户变量(静态变量不能unset,只读变量不可更改)
unset var_name

4.3、位置变量

位置变量也称位置参数,使用$0$1$2$9表示,位置变量属于只读变量,主要用于按照从左到右的顺序依次向Shell脚本传递参数,命令或脚本本身的名称使用$0表示,参数的个数可以任意多,$1~$9表示第1个到第9个参数,10个及以上的参数需要使用{}才能被访问到,例如第10个参数表示为${10}

以下是一个示例:

1) 编写脚本并保存:

vim add.sh
#!/bin/bash
echo "执行的文件名:$0";
echo "执行的脚本名: `basename $0`";
SUM=`expr $1 + $2` 
echo "$1 + $2 = $SUM"

2) 添加执行权限:

chmod +x add.sh 

3) 执行脚本:

./add.sh 2 3

脚本输出的结果如下:

执行的文件名:./add.sh
执行的脚本名: add.sh
2 + 3 = 5

4.4、特殊变量

特殊变量(预定义变量)是由Bash程序预先定义好的一类变量,特殊变量属于只读变量,反映Shell脚本运行过程中的控制信息,预定义变量使用$符号和另一个符号组合表示

  • $#:传递给脚本命令行中位置参数的数量
  • $*:列出命令行中的位置参数列表,所有参数看作一个整体字符串
  • $@:列出命令行中的位置参数列表,每个参数看作独立的字符串
  • $?:返回最后一行命令的执行退出状态,0表示执行成功,非0值表示执行出现异常
  • $0:返回当前执行的脚本或程序的路径名称
  • $$:返回当前Shell进程的进程号(PID)
  • $!:返回后台运行的最后一个进程号(PID)
  • $-:返回当前Shell的选项标志(不常用)
  • $IFS:返回Shell脚本中的字段分隔符(默认为空格+制表符+换行符),可重新指定

$*$@的区别如下:

  • 相同点:都是引用的所有位置参数
  • 不同点:只在双引号中,假设脚本传递了三个参数(1 2 3),*等价于"1 2 3"(1个字符串),@ 等价于"1" "2" "3"(3个字符串)
#!/bin/bash
echo "-- \$* 演示 ---"
for i in "$*"; do
    echo $i
done

echo "-- \$@ 演示 ---"
for i in "$@"; do
    echo $i
done

执行脚本,输出结果如下:

-- $* 演示 ---
1 2 3
-- $@ 演示 ---
1
2
3

5、变量中的特殊符号


5.1、字符串变量

5.1.1、字符串中的特殊符号

Shell字符串可以使用单引号,也可以使用双引号,也可以不使用引号

greeting=Hello
greeting='Hello'
greeting="Hello"

1)单引号

仅作为字符串使用。包含的变量将被当做字符串解释

echo '$greeting world'     # $greeting world
echo 'Today is `date`'     # Today is `date`

单引号字符串中不能出现单独一个的单引号,不能出现转义字符

2)双引号

双引号中可以引用变量,包含的变量将被解释

echo "$greeting world"     # hello world
echo "Today is `date`"     # Today is 2024年 08月 18日 星期日 18:30:05 CST

3)反引号

反引号和$()作用相同,主要用于执行命令并将其输出插入到命令行中

echo "`ls -l`"                  # 输出执行命令ls -l的结果
# 使用转义字符echo输出需要添加-e转义
echo -e "Today is \"`date`\""   # Today is "2024年 08月 18日 星期日 18:30:05 CST"
echo "`hostname`"               # 获取当前主机名
echo "`basename $0`"            # 获取执行的脚本名

5.1.2、字符串变量的操作

字符串变量的基本操作如下:

1)字符串拼接

greeting="Hello"
name="Tom"
# 直接拼接
echo $greeting$name     # HelloTom
# 使用双引号拼接
greeting_1="$greeting, $name !"
echo $greeting_1        # Hello, Tom !
# 使用单引号拼接
greeting_2=''$greeting', '$name' !'
echo $greeting_2        # Hello, Tom !

2)获取字符串长度

# 语法:${#string}
echo ${#greeting}          # 5
# 当变量为字符串时,${#string}等价于${#string[0]}
echo ${#greeting[0]}       # 5

3)提取子字符串

字符串第一个字符的索引值为0

# ${str:sta:len}:从字符串第2个字符开始截取3个字符
echo ${greeting:1:3}       # ell
# ${str:sta}:从字符串第2个字符开始截取(后面全部)
echo ${greeting:1}         # ello

4)字符串替换

# ${str/sub/new}:用new替换str中的第一个sub
echo ${greeting/l/t}       # Hetlo
# ${str//sub/new}:用new替换str中的全部sub
echo ${greeting//l/t}      # Hetto

5)查找子字符串的位置

# 查找字符e的位置(从1开始)
echo `expr index "$greeting" e`     # 2
# 查找子字符串lo的位置(从1开始)
echo `expr index "$greeting" lo`    # 4

5.1.3、正则表达式

正则表达式是用来匹配文本的强大工具。以下是一些基本的正则表达式符号:

  • .:匹配任意一个字符
  • *:匹配前面的字符0次或多次
  • +:匹配前面的字符1次或多次
  • ?:匹配前面的字符0次或1次
  • ^:匹配行首
  • $:匹配行尾
  • [abc]:匹配a、b、c中的任一个字符
  • [0-9]:匹配任意一个数字字符
  • \:转义特殊字符,使其被当作普通字符匹配

例如,正则表达式a.*b可以匹配以a开头,以b结束的任意字符串

更多关于正则表达式的介绍和使用详见文章:传送门

5.2、数组变量

5.2.1、数组中的特殊符号

数组中的特殊符号基本使用如下:

# 1)打印数组
# 方式1
echo ${my_array[@]}      # A B C D
# 方式2
echo ${my_array[*]}      # A B C D
# 2)获取数组元素的数量(获取数组长度/大小)
# 方式1
echo ${#my_array[@]}      # 4
# 方式2
echo ${#my_array[*]}      # 4
# 3)访问数组元素(下标从0开始)
echo ${my_array[2]}       # B
# 4)取得数组中某个元素的长度
echo ${#my_array[2]}      # 1

5.2.2、数组变量的操作

数组变量的常见操作包括但不限于:

1)数组遍历

# 方式1
for i in ${my_array[@]}; do
    echo $i
done
# 方式2
for ((i = 0; i < ${#my_array[@]}; i++)); do
    echo ${my_array[i]}
done
# 方式3
i=0
while [ $i -lt ${#my_array[@]} ]; do
    echo ${my_array[$i]}"
done

2)数组截取(切片)

语法格式:${arr[@]:sta:len}sta为闭区间,不改变原数组)

# 从起始索引1开始,截取2个元素
echo ${my_array[@]:1:2}      # B C
# 截取起始位置及后面的全部元素:${arr[@]:sta}
echo ${my_array[@]:2}        # C D
# 截取前n(2)个元素:${arr[@]:0:n}
echo ${my_array[@]:0:2}      # A B
# 截取后n(2)个元素:${arr[@]:$((${#arr[@]}-n)):n}
echo ${my_array[@]:$((${#my_array[@]}-2)):2}    # C D

3)数组删除

# 删除数组元素(删除第二个元素)
unset my_array[1]
echo ${my_array[@]}            # A C D
# 删除数组
unset my_array
echo ${my_array[@]}            #

4)数组替换

语法格式:${arr[@]/old/new}(不改变原数组)

# 将D替换为E
echo ${my_array[@]/D/E}         # A B C E
# 改变原数组(重新赋值):arr[index]=value
my_array[1]=E
echo ${my_array[@]}             # E B C D

5)数组扩容

向数组追加元素的常见方法如下:

# 方式1:使用索引:将数组长度作为新元素索引进行追加
arr[${#arr[@]}]=value
# 方式2:使用+=()操作符:必须使用(),多个元素使用空格隔开,在数组末尾追加元素或数组
arr+=(value1 value2 ...)
# 方式3:使用数组展开:使用数组展开追加元素,多个元素使用空格隔开
# 使用注意:必须使用双引号和@,否则包含空格的元素将被拆分为多个元素
arr=("${arr[@]}" value1 value2 ...)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值