Linux Shelll脚本之变量用法大全

本篇主要介绍Shell变量相关,包括变量基础知识、变量使用进阶、位置参数的使用、特殊变量的使用、为变量定义默认值以及变量值截取、变量值替换等。

1,变量基础知识

1.1、变量定义

如下为几个简单的变量示例

MY_VAR="Hello, World!"
MAX_COUNT=10
FILE_PATH="/home/user/file.txt"

常见的规范:

  • 在 Shell 中定义变量时,变量名和等号之间不能有空格。
  • 变量名通常使用大写字母,以便与命令和其他变量区分开来,变量名包含多个单词时使用下划线进行分隔。
  • 变量值尽量使用双引号包围起来,以防止值中存在空格或特殊字符引发错误。
  • 变量值可以包含其他变量,但是需要使用花括号 {} 来明确变量的边界。

1.2、变量使用

引用变量时,需要在变量前加上美元符号 $ :

NAME="tigerhhzz"
echo "My name is $NAME"

在这里插入图片描述

2,变量使用进阶

2.1、变量值中包含变量

基于执行时间写入新的日志文件:

[root@tigerhhzz01 test]# cat t1.sh
#!/bin/bash

LOG_PATH="/root/test"
NOW_TIME="$(date +%Y%m%d_%H%M%S)"
LOG_FILE="${LOG_PATH}/start_${NOW_TIME}.log"

echo "当前日志将写入文件:${LOG_FILE}"
[root@tigerhhzz01 test]# 

[root@tigerhhzz01 test]# sh t1.sh
当前日志将写入文件:/root/test/start_20241001_200101.log
[root@tigerhhzz01 test]# 
[root@tigerhhzz01 test]# sh t1.sh
当前日志将写入文件:/root/test/start_20241001_200104.log
[root@tigerhhzz01 test]# 

2.2、截取字符串内容同时定义多个变量

使用 eval 和 awk 命令实现,将字符串中空格分隔的多个字段分别赋值给指定变量。

[root@tigerhhzz01 test]# cat t2.sh
#!/bin/bash

NOW_LINE="1008858 tigerhhzz 18"
eval $(echo "$NOW_LINE" |awk '{printf("KEY_ID=%s; KEY_NAME=%s; KEY_AGE=%s",$1,$2,$3)}')

echo "ID:${KEY_ID} ,姓名:${KEY_NAME} , 年龄:${KEY_AGE}"
[root@tigerhhzz01 test]# 

[root@tigerhhzz01 test]# sh t2.sh
ID:1008858 ,姓名:tigerhhzz , 年龄:18
[root@tigerhhzz01 test]# 

2.3、获取用户的输入定义变量

使用 read 命令实现,可以读取定义单个变量或读取定义多个变量(以空格分隔多个值)。

[root@tigerhhzz01 test]# cat t3.sh
#!/bin/bash

echo "请输入空格分隔的两个内容:"
read KEY_NAME KEY_AGE

echo "第一个值为:${KEY_NAME},第二个值为:${KEY_AGE}"
[root@tigerhhzz01 test]# 

[root@tigerhhzz01 test]# sh t3.sh
请输入空格分隔的两个内容:
tigerhhzz 18
第一个值为:tigerhhzz,第二个值为:18
[root@tigerhhzz01 test]# 

也可以使用 -p 选项设置输入提示符:

[root@tigerhhzz01 test]# cat t3-2.sh
#!/bin/bash

read -p "请输入您的国家: " KEY_COUNTRY
echo "您输入的国家是: ${KEY_COUNTRY}"

[root@tigerhhzz01 test]# sh t3-2.sh
请输入您的国家: 中国
您输入的国家是: 中国
[root@tigerhhzz01 test]# 

3,位置参数的使用

在 Shell 脚本中,你可以使用位置参数来处理用户输入的传参。位置参数是传递给脚本或函数的参数,通常通过 $1, $2, $3 … $9 等等来访问(超过9个的位置参数引用时需要使用花括号围起来,例如使用 ${10} 来获取第10个参数的值)。如果你希望处理任意数量的参数,你还可以使用 $@ 和 $* 来引用所有的参数。另外可以使用 $0 获取脚本的名称,使用 $# 来获取传递给脚本的参数的个数。

[root@tigerhhzz01 test]# cat t4.sh
#!/bin/bash

# 打印第一个和第二个参数
echo "第一个参数: $1"
echo "第二个参数: $2"

echo "当前 Shell 脚本名称为:$0 ,你总共输入了 $# 个参数"

[root@tigerhhzz01 test]# sh t4.sh a b c
第一个参数: a
第二个参数: b
当前 Shell 脚本名称为:t4.sh ,你总共输入了 3 个参数
[root@tigerhhzz01 test]# 

3.1、不被双引号包围

在 Shell 脚本中引用所有的参数时,如果 $* 和 $@ 不被双引号包围,‌它们之间没有任何区别,‌都将接收到的每个参数视为独立的单元,‌参数之间以空格分隔。

[root@tigerhhzz01 test]# cat t4-2.sh
#!/bin/bash

echo "如下为 \$*"
for i in $* ; do
    echo $i
done

echo "如下为 \$@"
for i in $@ ; do
    echo $i
done

[root@tigerhhzz01 test]# sh t4-2.sh a b c
如下为 $*
a
b
c
如下为 $@
a
b
c
[root@tigerhhzz01 test]# 

3.2、被双引号包围

如果被双引号包围起来,区别就显现出来了。 $*会将所有参数视为一个整体(作为一个单一的字符串处理),而 $@ 仍然将每个参数视为独立的单元。这种区别在处理参数时尤为重要。

[root@tigerhhzz01 test]# cat t4-3.sh
#!/bin/bash

echo "如下为 \$*"
for i in "$*" ; do
    echo $i
done

echo "如下为 \$@"
for i in "$@" ; do
    echo $i
done

[root@tigerhhzz01 test]# sh t4-3.sh a b c
如下为 $*
a b c
如下为 $@
a
b
c
[root@tigerhhzz01 test]# 

4,特殊变量的使用

除了上面的位置参数外,在 Shell 脚本中还有一些其他的特殊变量,如下所示。

4.1、$? 获取上一个命令的退出状态码

值为 0 表示执行成功,非 0 表示执行失败。

[root@tigerhhzz01 test]# cat t5-1.sh
#!/bin/bash

echo "$1" |grep hello
echo "grep 命令退出状态码为:$?"

[root@tigerhhzz01 test]# sh t5-1.sh
grep 命令退出状态码为:1
[root@tigerhhzz01 test]# sh t5-1.sh hello
hello
grep 命令退出状态码为:0
[root@tigerhhzz01 test]# 

4.2、$$ 获取当前脚本的进程ID(PID)

[root@tigerhhzz01 test]# cat t5-2.sh
#!/bin/bash

echo "当前脚本的进程ID为:$$" >/root/test/my.pid
sleep 100
[root@tigerhhzz01 test]# nohup sh t5-2.sh &
[1] 1085578
[root@tigerhhzz01 test]# nohup: ignoring input and appending output to 'nohup.out'

[root@tigerhhzz01 test]# cat my.pid
当前脚本的进程ID为:1085578
[root@tigerhhzz01 test]# 
[root@tigerhhzz01 test]# ps -ef |grep t5-2 |grep -v grep
root     1085578 1085369  0 20:32 pts/0    00:00:00 sh t5-2.sh
[root@tigerhhzz01 test]# 

4.3、$! 获取最后一个后台运行进程的ID(PID)

[root@tigerhhzz01 test]# cat t5-3.sh
#!/bin/bash

nohup sh /root/test/t5-2.sh &
echo "上一个后台运行的进程的PID为:$!"
[root@tigerhhzz01 test]# sh t5-3.sh
上一个后台运行的进程的PID为:1085609
[root@tigerhhzz01 test]# 
[root@tigerhhzz01 test]# ps -ef |grep t5-2 |grep -v grep
root     1085609       1  0 20:38 pts/0    00:00:00 sh /root/test/t5-2.sh
[root@tigerhhzz01 test]# 

4.4、$- 获取当前shell选项

[root@tigerhhzz01 test]# cat t5-4.sh
#!/bin/bash

echo $-

[root@tigerhhzz01 test]# sh t5-4.sh
hB
[root@tigerhhzz01 test]# sh -x t5-4.sh
+ echo hxB
hxB
[root@tigerhhzz01 test]# 

5,为变量设置默认值

常用有两种。当变量没有被定义或为空时,一种只返回默认值不会修改变量,另一种则会设置变量为默认值。

5.1、:-

如果变量 VAR 没有被定义或为空,则返回默认值(VAR本身没有任何改变)。


[root@tigerhhzz01 test]# cat t6-1.sh
#!/bin/bash

echo "如下为未定义变量时"
unset VAR
RESULT=${VAR:-"默认值"}
echo "RESULT: $RESULT"
echo "VAR: $VAR"


echo "如下为定义变量后"
VAR="Hello"
RESULT=${VAR:-"默认值"}
echo "RESULT: $RESULT"
echo "VAR: $VAR"
[root@tigerhhzz01 test]#

[root@tigerhhzz01 test]# sh t6-1.sh
如下为未定义变量时
RESULT: 默认值
VAR:
如下为定义变量后
RESULT: Hello
VAR: Hello
[root@tigerhhzz01 test]#

5.2、:=

如果变量 VAR 没有被定义或为空,则设置变量 VAR 的值为默认值,并返回其值(VAR发生改变)。


[root@tigerhhzz01 test]# cat t6-2.sh
#!/bin/bash

echo "如下为未定义变量时"
unset VAR
RESULT=${VAR:="默认值"}
echo "RESULT: $RESULT"
echo "VAR: $VAR"


echo "如下为定义变量后"
VAR="Hello"
RESULT=${VAR:="默认值"}
echo "RESULT: $RESULT"
echo "VAR: $VAR"
[root@tigerhhzz01 test]#

[root@tigerhhzz01 test]# sh t6-2.sh
如下为未定义变量时
RESULT: 默认值
VAR: 默认值
如下为定义变量后
RESULT: Hello
VAR: Hello
[root@tigerhhzz01 test]#

6、变量值截取

6.1、获取变量值的字符个数

[root@tigerhhzz01 test]# cat t8-1.sh
#!/bin/bash

VAR="$1"
echo "输入的字符长度为:${#VAR}"
[root@tigerhhzz01 test]#

[root@tigerhhzz01 test]# sh t8-1.sh
输入的字符长度为:0
[root@tigerhhzz01 test]#
[root@tigerhhzz01 test]# sh t8-1.sh hello
输入的字符长度为:5
[root@tigerhhzz01 test]#

6.2、截取变量值的指定个数字符

从左边开始


// 其中的 0 表示左边第一个字符开始,5 表示字符的总个数。
[root@tigerhhzz01 test]# VAR=https://www.example.com/index.html
[root@tigerhhzz01 test]# echo ${VAR:0:5}
https
[root@tigerhhzz01 test]#

从左边开始

// 其中的 0-10 表示右边算起第十个字符开始,5 表示字符的个数。
[root@tigerhhzz01 test]# VAR=https://www.example.com/index.html
[root@tigerhhzz01 test]# echo ${VAR:0-10:5}
index
[root@tigerhhzz01 test]#

6.3、截取指定位置到结束字符

从左到右数第几个字符开始到结束


// 其中的 8 表示左边第9个字符开始,一直到结束。
[root@tigerhhzz01 test]# VAR=https://www.example.com/index.html
[root@tigerhhzz01 test]# echo ${VAR:8}
www.example.com/index.html
[root@tigerhhzz01 test]#

从右到左第几个字符开始到结束

// 表示从右边第四个字符开始,一直到结束。
[root@tigerhhzz01 test]# VAR=https://www.example.com/index.html
[root@tigerhhzz01 test]# echo ${VAR:0-4}
html
[root@tigerhhzz01 test]#

6.4、截取变量值保留右边字符

一个#符号截取,最短匹配

// 其中 VAR 是变量名,#符号是运算符,*// 表示从左边开始删除第一个 // 号及左边的所有字符,即删除 https://
[root@tigerhhzz01 test]# VAR=https://www.example.com/index.html
[root@tigerhhzz01 test]# echo ${VAR#*//}
www.example.com/index.html
[root@tigerhhzz01 test]#

两个#符号截取,最长匹配

// 其中 ##*/ 表示从左边开始删除最后(最右边)一个 / 号及左边的所有字符,即删除 https://www.example.com/
[root@tigerhhzz01 test]# VAR=https://www.example.com/index.html
[root@tigerhhzz01 test]# echo ${VAR##*/}
index.html
[root@tigerhhzz01 test]#

6.5、截取变量值保留左边字符

一个%符号截取,最短匹配

// 其中 %/* 表示从右边开始,删除第一个 / 号及右边的字符,即删除 /index.html
[root@tigerhhzz01 test]# VAR=https://www.example.com/index.html
[root@tigerhhzz01 test]# echo ${VAR%/*}
https://www.example.com
[root@tigerhhzz01 test]#

两个%符号截取,最长匹配

// 其中 %%/* 表示从右边开始,删除最后(最左边)一个 / 号及右边的字符,即删除 //www.example.com/index.html
[root@tigerhhzz01 test]# VAR=https://www.example.com/index.html
[root@tigerhhzz01 test]# echo ${VAR%%/*}
https:
[root@tigerhhzz01 test]#

7、变量值替换

7.1、字母大写转换为小写

两个 , 符号,如果变量 VAR 中包含大写字母,则这些字母都会被转换为小写字母。

[root@tigerhhzz01 test]# VAR="Hello, World!"
[root@tigerhhzz01 test]# echo "${VAR,,}"
hello, world!
[root@tigerhhzz01 test]#

单个 , 符号,如果变量 VAR 中首个字符为大写字母,则这个字母将被转换为小写字母。

[root@tigerhhzz01 test]# VAR="Hello, World!"
[root@tigerhhzz01 test]# echo "${VAR,}"
hello, World!
[root@tigerhhzz01 test]#

7.2、字母小写转换为大写

两个 ^ 符号,如果变量 VAR 中包含小写字母,则这些字母都会被转换为大写字母。

[root@tigerhhzz01 test]# VAR="Hello, World!"
[root@tigerhhzz01 test]# echo "${VAR^^}"
HELLO, WORLD!
[root@tigerhhzz01 test]#

单个 ^ 符号,如果变量 VAR 中首个字符为小写字母,则这个字母将被转换为大写字母。

[root@tigerhhzz01 test]# VAR="hello, World!"
[root@tigerhhzz01 test]# echo "${VAR^}"
Hello, World!
[root@tigerhhzz01 test]#

7.3、字符替换

单个 / 符号,替换第一个匹配的字符

[root@tigerhhzz01 test]# VAR="hello,zhangsan. hello lisi"
[root@tigerhhzz01 test]# echo ${VAR/hello/nihao}
nihao,zhangsan. hello lisi
[root@tigerhhzz01 test]#

两个 / 符号,替换所有匹配的字符

[root@tigerhhzz01 test]# VAR="hello,zhangsan. hello lisi"
[root@tigerhhzz01 test]# echo ${VAR//hello/nihao}
nihao,zhangsan. nihao lisi
[root@tigerhhzz01 test]#

在这里插入图片描述


不要停止奔跑,不要回顾来路,来路无可眷恋,值得期待的只有前方。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

hhzz

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值