shell 脚本语言的变量用法示例详解
作者:下一期明天更
1、变量
变量表示命名的内存空间,将数据放在内存空间中,通过变量名引用,获取数据
2、 变量类型
变量类型:
- 内置变量:如PS1,PATH,UID,HOSTNAME,HISTSIZE
- 用户自定义变量
- 预定义变量
- 位置变量
不同的变量存放的数据不同,决定了以下:
- 数据存储方式
- 参与的计算
- 表示的数据范围
变量数据类型:
- 字符串
- 数值:整型,浮点型(小数)、bash不支持浮点数
3、 Shell中变量命名法则
- 不能使用程序中的保留字,如:if,for
- 只能使用数字,字母及下划线,且不能以数字开头
- 见名思意,用英文名字,并体现真正含义
- 统一命名规则:驼峰命名法(比如:varName)
- 全局变量名大写
- 局部变量小写
- 函数名小写
4、 变量定义和引用
变量的生效范围(变量作用域)
- 普通变量(局部):生效范围为当前shell进程;对当前shell之外的其他shell进程,包括当前shell的子shell进程均无效
- 环境变量(全局):生效范围为当前shell进程及其子进程
- 本地变量(局部):生效范围为当前shell进程中某代码片段,通常指函数
变量赋值:
name="value" value可以是以下多种类型 直接字符串:name='root' 变量引用:name="$USER" 命令应用:name=`command` || name=$(command) 通配符:FILE=/etc/* /*表示etc目录下所有的文件名*/
注意:变量赋值是临时生效,当退出终端后,变量会自动删除,无法持久保存。
变量引用:
$name ${name}
弱引用和强引用:
- “$name”:弱引用,其中的变量引用会被替换成为变量值
- ‘$name’:强引用,其中的变量引用不会被替换成变量值,而保持原字符串
实例:
[root@localhost ~]# name='Mike' [root@localhost ~]# NAME="$USER" [root@localhost ~]# hostname=`hostname` [root@localhost ~]# echo "My name is $name" My name is Mike [root@localhost ~]# echo "My name is $NAME" My name is root [root@localhost ~]# echo "My hostname is $hostname" My hostname is localhost.localdomain [root@localhost ~]# [root@localhost ~]# NUM=`seq 10` [root@localhost ~]# echo $NUM 1 2 3 4 5 6 7 8 9 10 [root@localhost ~]# echo "$NUM" 1 2 3 4 5 6 7 8 9 10 [root@localhost ~]#
查看已定义的所有变量:
[root@localhost ~]#set
删除变量
[root@localhost ~]#unset shellname1 shellname2 //实例: [root@localhost ~]# echo $name Mike [root@localhost ~]# unset name [root@localhost ~]# echo $name [root@localhost ~]#
实例:"{}"的使用
[root@localhost ~]# NAME=mage [root@localhost ~]# AGE=20 [root@localhost ~]# echo $NAME mage [root@localhost ~]# echo $AGE 20 [root@localhost ~]# echo $NAME $AGE mage 20 [root@localhost ~]# echo $NAME_$AGE 20 [root@localhost ~]# echo ${NAME}_$AGE mage_20 [root@localhost ~]#
显示系统信息
[root@localhost ~]# vim shell/OS.sh #!/bin/bash RED="\E[1;31m" GREEB="\E[1;32m" END="\E[0m" echo -e "\E[1;32m----------Host systeminfo----------$END" echo -e "HOSTNAME: $RED `hostname`$END" echo -e "IPADDR: $RED `ifconfig ens160 | grep -Eo '([0-9]{1,3}\.){3}[0-9]{1,3}' | head -n1` $END" echo -e "OSVERSION: $RED `cat /etc/redhat-release`$END" echo -e "KERNEL: $RED `uname -r`$END" echo -e "CPU: $RED `lscpu | grep "型号名称:" | tr -s ' ' ' '|cut -d ' ' -f 2-5` $END" echo -e "MEMORY: $RED `free -h | grep Mem | tr -s ' ' ' '|cut -d ' ' -f 4` $END" echo -e "DISK: $RED `lsblk | grep '^sda' | tr -s ' ' | cut -d ' ' -f 4` $END" echo -e "\E[1;32m---------- END ----------$END" [root@localhost ~]# chmod +x shell/OS.sh [root@localhost shellScript]# ./os.sh ----------Host systeminfo---------- HOSTNAME: localhost.localdomain IPADDR: 192.168.115.213 OSVERSION: CentOS Linux release 7.9.2009 (Core) KERNEL: 3.10.0-1160.el7.x86_64 CPU: 11th Gen Intel(R) Core(TM) MEMORY: 1.0G DISK: 200G ---------- END ----------
利用变量实现动态命令
[root@localhost ~]# CMD=hostname [root@localhost ~]# $CMD localhost.localdomain [root@localhost ~]#
5、 环境变量
环境变量:
- 可以使子进程(包括孙子进程)继承父进程的变量,但是无法让父进程使用子进程的变量。
- 一旦子进程修改了从父进程继承的变量,将会传递新的值给孙子进程
- 一般只在配置文件中使用,在脚本中较少使用
课程引入:普通变量生效的范围与环境变量生效的范围
[root@localhost ~]# vim shell/father.sh #!/bin/bash NAME=father echo "father.sh:NAME=$NAME" echo "fatther is PID=$BASHPID" shell/son.sh [root@localhost ~]#vim shell/son.sh #!/bin/bash echo "son.sh:NAME=$NAME" NAME=son echo "son.sh:NAME=$NAME" echo "son.sh PID is $BASHPID" echo "son.sh father pid is $PPID" sleep 100 [root@localhost ~]#chmod -R +x shell/* [root@localhost ~]# ./shell/father.sh father.sh:NAME=father fatther is PID=12053 son.sh:NAME= son.sh:NAME=son son.sh PID is 12054 son.sh father pid is 12053 #子进程无法使用父进程的变量,需要自己赋值
变量声明和赋值:
export name=VALUE declare -x name =VALUE #或者先赋值再声明~ value可以是以下多种类型 直接字符串:name='root' 变量引用:name="$USER" 命令应用:name=`command` || name=$(command) 通配符:FILE=/etc/* /*表示etc目录下所有的文件名*/
declare命令详解:(了解)
declare 为 shell 指令,在第一种语法中可用来声明变量并设置变量的属性([rix]即为变量的属性),在第二种语法中可用来显示 shell 函数。若不加上任何参数,则会显示全部的 shell 变量与函数(与执行 set 指令的效果相同)
语法
declare [+/-][rxi][变量名称=设置值] 或 declare -f
参数说明:
- +/- "-“可用来指定变量的属性,”+"则是取消变量所设的属性。
- -f 仅显示函数
- r 将变量声明为只读变量。注意,一旦设置为只读变量,既不能修改变量的值也不能删除变量,甚至不能通过+r取消只 读属性
- x 指定的变量会成为环境变量,可供shell以外的程序来使用
- i 将变量声明为整数型(integer)
- p 显示指定变量的被声明类型。
实例
1.声明整数型变量
#!/bin/bash declare -i ab //声明整数型变量 ab=56 //改变变量内容 echo $ab //显示变量内容 ---> 56
2.改变变量属性
#!/bin/bash #声明整数型变量 declare -i ef ef=1 echo $ef #变量赋值,赋予文本值 ef="wer" echo $ef #取消变量属性 declare +i ef ef="wer" echo $ef
3.设置变量只读
#!/bin/bash declare -r ab #设置变量为只读 ab=88 #改变变量内容 echo $ab #显示变量内容 ---> declare.sh:行3: ab: 只读变量
4.声明数组变量
#!/bin/bash #声明数组变量 declare -a cd cd[0]=a cd[1]=b cd[2]=c #输出数组的指定内容 echo ${cd[1]} #显示整个数组变量内容 echo ${cd[@]}
5.显示函数
#!/bin/bash #声明函数 declare -f function command_not_found_handle(){ if [ -x /usr/lib/command_not_found_handle ];then /usr/bin/python /usr/lib/command_not_found_handle -- $1; return $?; else if [ -x /usr/share/command_not_found_handle ];then /usr/bin/python /usr/share/command_not_found_handle --$1; return $?; else return 127; fi; fi; }
变量引用:
$name ${name}
完善课程导入:
[root@localhost ~]# vim shell/father.sh #!/bin/bash NAME=father export NAME echo "father.sh:NAME=$NAME" echo "fatther is PID=$BASHPID" shell/son.sh [root@localhost ~]#vim shell/son.sh #!/bin/bash echo "son.sh:NAME=$NAME" NAME=son echo "son.sh:NAME=$NAME" echo "son.sh PID is $BASHPID" echo "son.sh father pid is $PPID" sleep 100 [root@localhost ~]#chmod -R +x shell/* [root@localhost ~]# ./shell/father.sh father.sh:NAME=father fatther is PID=12053 son.sh:NAME=father son.sh:NAME=son son.sh PID is 12054 son.sh father pid is 12053 [root@localhost ~]# ./shell/father.sh father.sh:NAME=father fatther is PID=12142 son.sh:NAME=father son.sh:NAME=son son.sh PID is 12143 son.sh father pid is 12142 #父进程定义了一个环境变量,在子进程上可以进行调用 #父进程无法使用子进程的变量 #子进程自己定义了一个同名变量,就覆盖环境变量
显示所有环境变量:
[root@localhost ~]# env [root@localhost ~]# printenv [root@localhost ~]# export [root@localhost ~]# declare -x
删除变量:
[root@localhost ~]#unset shellname1 shellname2
Bash内建的环境变量
PATH SHELL USER UID PWD SHLVL #shell的嵌套层数,即深度 LANG MAIL HOSTNAME HISTSIZE _ #下划线,表示前一命令的最后一个参数
6、只读变量
只读变量:只能声明定义,但后续不能修改和删除
- 声明只读变量:
readonly name declare -r name
- 查看只读变量:
readonly [-p] declare -r
7、位置与预定义变量
位置变量:在Bash Shell中内置的变量,在脚本代码中调用命令行传递给脚本的参数
$1,$2,... 对应第一个,第二个等参数,shift[n]换位置,最多9个 #预定义变量 $0 脚本本身,包括路径 $* 传递给脚本的所有参数,全部参数合成一个字符串 $@ 传递给脚本的所有参数,每个参数为独立字符串 $# 传递给脚本的参数的个数 $? 上个命令的退出状态,或函数的返回值 $$ 当前shell进程ID。对于Shell脚本,就是这些脚本所在的进程ID 注意:$@,$*只有被双引号括起来的时候才会有差异
清空所有位置变量
set -- //写在脚本内部
实例演示1:
[root@localhost ~]# vim ARG.sh #!/bin/bash echo "1st arg is $1" echo "2st arg is $2" echo "3st arg is $3" echo "4st arg is $4" echo "The number of are is $#" echo "All args are $*" echo "All args are $@" echo "The scriptname is `basename $0`" [root@localhost ~]# chmod +x shell/ARG.sh [root@localhost ~]# shell/ARG.sh {1..10} 1st arg is 1 2st arg is 2 3st arg is 3 4st arg is 4 The number of are is 10 All args are 1 2 3 4 5 6 7 8 9 10 All args are 1 2 3 4 5 6 7 8 9 10 The scriptname is ARG.sh [root@localhost ~]#
实例演示2:编写一个移动文件脚本
[root@localhost ~]# vim move.sh #!/bin/bash WANGING_COLOR="echo -e \E[1;31m" END="\E[0m" DIR=/tmp/`date +%F_%H-%M-%S` mkdir $DIR mv $* $DIR ${WANGING_COLOR} MOVE $* to $DIR $END [root@localhost ~]# chmod +x shell/move.sh [root@localhost ~]# touch {a,b,c} [root@localhost ~]# ls a anaconda-ks.cfg b c shell [root@localhost ~]# shell/move.sh a b c MOVE a b c to /tmp/2022-08-16_10-07-55 [root@localhost ~]# tree /tmp/ /tmp/ └── 2022-08-16_10-07-55 ├── a ├── b └── c 1 directory, 3 files [root@localhost ~]#
8、 退出状态码变量
进程执行后,将使用变量 ? 保存状态码的相关数字,不同的值反应成功与失败, ?保存状态码的相关数字,不同的值反应成功与失败, ?保存状态码的相关数字,不同的值反应成功与失败,的取值范围为[0,255]
$?的值为0 代表成功 $?的值不为0 代表失败
用户可以在脚本中使用以下命令自定义退出状态码
exit [n]
实例:
[root@localhost ~]# ping -c 2 www.baidu.com > /dev/null [root@localhost ~]# echo $? 0 [root@localhost ~]# cmd -bash: cmd: 未找到命令 [root@localhost ~]# echo $? 127 [root@localhost ~]#
注意:
- 脚本中一旦遇到了exit命令,脚本会立即终止;终止退出状态取决于exit命令后面的数字
- 如果未给脚本指定退出状态码,整个脚本的退出状态码取决于脚本中执行的最后一条命令的状态码
实例1:$?获取上一个命令的退出状态
#!/bin/bash if [ "$1"==100 ];then exit 0 #参数正确,退出状态为0 else exit 1 #参数错误,退出状态为1 fi
exit
表示退出当前 Shell 进程,我们必须在新进程中运行 test.sh,否则当前 Shell 会话(终端窗口)会被关闭,我们就无法取得它的退出状态了
[root@localhost re_study]# bash test.sh 100 [root@localhost re_study]# echo $? 0 [root@localhost re_study]# bash test.sh 99 [root@localhost re_study]# echo $? 1 [root@localhost re_study]#
实例2:$?获取函数的返回值
#!/bin/bash #得到两个数相加的和 function add(){ return `expr $1 + $2` } add 23 50 #调用函数 echo $? #获取函数返回值
# 运行结果: [root@localhost re_study]# bash test.sh 73
9、 展开命令行
9.1展开命令执行顺序
把命令行分成单个命令词 展开别名 展开大括号的声明{} 展开波浪符声明(~) 命令替换$()和`` 再次把命令行分成命令词 展开文件通配(*,?,[abc]等) 准备I/O重导向(<,>) 运行命令
9.2 防止扩展
反斜线(\)会使随后的字符按原意解释
实例:
[root@localhost ~]# echo Your cost: \$5.00 Your cost: $5.00 [root@localhost ~]#
9.3 加引号来防止扩展
单引号 ' ' 防止所有扩展;保留字符原意 双引号 " " 可防止扩展;保留shell中字符的特俗含义
括号的作用: ():执行内部命令时会开启子shell [] : 用于条件判断或数学运算 {} : 执行内部命令时不开启子shell $括号的作用: $() : 相当于 $[] : 数学运算 ${} : 区别变量名
9.4 变量扩展
``:反引号,命令替换;引用引号内命令的执行结果 \:反斜线,禁止单个字符扩展 !:叹号,历史命令替换
转义符:\ 转换原意: \n : 换行 \t : 水平制表符tab键 ,字符间距 \v : 垂直制表符 ,行间距 \r : 回车,提交作用的 转换现有含义: \$ : 屏蔽引用变量的含义 \` \" \'
10、 脚本安全和set(暂时不用)
set命令:可以用来定制shell环境
10.1 $-变量
- h:hashell,打开选项后,Shell会将命令所在的路径hash下来,避免每次都要查询。通过set +h将h选项关闭.默认开启
- i:interactive-comments,包含这个选项说明当前的shell是一个交互式的shell。所谓的交互式shell,在脚本中,i选项是关闭的
- m:monitor,打开监控模式,就可以通过Job control来控制进程的停止,继续,后台或者前台执行等
- B:braccexpand,大括号扩展
- H:history,H选项打开,可以展开历史列表中的命令,可以通过
!
来完成,例如!!
返回最近的一个历史命令,!n
返回第n个历史命令
实例:
[root@localhost ~]# echo $- himBHs [root@localhost ~]# hash 命中 命令 1 /usr/sbin/ping [root@localhost ~]# set +h [root@localhost ~]# echo $- imBHs [root@localhost ~]# hash -bash: hash: 已禁用哈希 [root@localhost ~]# [root@localhost ~]# echo {1..10} 1 2 3 4 5 6 7 8 9 10 [root@localhost ~]# set +B [root@localhost ~]# echo {1..10} {1..10} [root@localhost ~]# [root@localhost ~]# set +H [root@localhost ~]# history !! -bash: history: !!: 需要数字参数 [root@localhost ~]# history !3 -bash: history: !3: 需要数字参数 [root@localhost ~]# set -H [root@localhost ~]# history !! history set -H -bash: history: set: 需要数字参数 [root@localhost ~]# history !3 history ifconfg -bash: history: ifconfg: 需要数字参数 [root@localhost ~]#
10.2 set命令实现脚本安全
- -u:在扩展一个没有设置的变量时,显示错误信息,等同于set -o nounset
- -e:如果一个命令返回一个非0退出的状态值(失败)就退出,等同于set -o errexit
- -o:option 显示,打开或关闭选项
- 显示选项:set -o
- 打开选项:set -o 选项
- 关闭选项:set +o 选项
- -x:当执行命令时,打印命令及其参数,类似bash -x
实例:
[root@localhost ~]# set -o allexport off braceexpand off emacs on errexit off errtrace off functrace off hashall on histexpand on history on ignoreeof off interactive-comments on keyword off monitor on noclobber off noexec off noglob off nolog off notify off nounset off onecmd off physical off pipefail off posix off privileged off verbose off vi off xtrace off [root@localhost ~]# vim shell/error.sh #!/bin/bash echo "Hello World" sssss echo "Hello Linux" [root@localhost ~]# chmod +x shell/error.sh [root@localhost ~]# shell/error.sh Hello World shell/error.sh:行3: sssss: 未找到命令 Hello Linux [root@localhost ~]# vim shell/error.sh #!/bin/bash set -e echo "Hello World" sssss echo "Hello Linux" [root@localhost ~]# shell/error.sh Hello World shell/error.sh:行4: sssss: 未找到命令 [root@localhost ~]#
到此这篇关于shell 脚本语言的变量用法示例详解的文章就介绍到这了,更多相关shell 变量用法内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!