shell 脚本 - 变量

变量基础概念

变量类型

内置变量(环境变量) ,如:PS1,PATH,UID,HOSTNAME,$ , B A S H P I D , P P I D , ,BASHPID,PPID, ,BASHPID,PPID,?,HISTSIZE 等
用户自定义变量

数据类型:字符和数值。数值包含整型、浮点型,bash 不支持浮点数

变量命名法则

1 不能使用程序中的关键字和内置变量,如:if,for
2 只能使用数字、字母及下划线,且不能以数字开头。注意:不支持短横线“-”,和主机名相反
3 见名知意,建议用英文单词命名,并体现实际作用,最好不要用简写
4 统一命名规则:驼峰命名法(studentname),大驼峰(StudentName),小驼峰(studentName)
5 变量名大写:STUDENT_NAME
6 局部变量小写
7 函数名小写

变量定义和应用

变量的生效范围等标准划分变量类型

普通变量:生效范围为当前shell 进程;对当前shell 之外的其他shell 进程,包括当前shell 的子shell 进程均无效

环境变量:生效范围为当前shell 进程及其子进程

本地变量:生效范围为当前shell 进程中某代码片段,通常指函数

变量赋值

name='value'

value的多种形式
直接字符串	name='root'
变量引用	name="$USER"
命令引用	name=`COMMAND` 或者 name=$(COMMAND)

需要注意的是:

变量赋值是临时生效,当退出终端后,变量会自动删除,无法持久保存。脚本中的变量也会随着脚本结束,自动删除

变量引用

$name${name} 	建议使用${name}

"$name" 弱引用,其中的变量引用会被替换为变量值
'$name' 强引用,其中的变量引用不会被替换为变量值,而保持原字符串

范例:变量的各种赋值方式和引用

#变量的赋值方式
[root@CentOS8 ~]#TITLE='cto'
[root@CentOS8 ~]#echo $TITLE
cto
[root@CentOS8 ~]#TITLE='cto'
[root@CentOS8 ~]#echo $TITLE
cto
[root@CentOS8 ~]#echo "i am $TITLE"
i am cto
[root@CentOS8 ~]#echo 'i am $TITLE'
i am $TITLE

[root@CentOS8 ~]#FILE=`ls /run`
[root@CentOS8 ~]#echo $FILE
agetty.reload auditd.pid console cron.reboot cryptsetup dbus faillock fsck initctl initramfs lock log mount NetworkManager plymouth rsyslogd.pid sepermit setrans sshd.pid sssd.pid sudo systemd tmpfiles.d tuned udev user utmp vmware

#变量的引用
[root@CentOS8 ~]#NAME=dawn
[root@CentOS8 ~]#AGE=17
[root@CentOS8 ~]#echo $NAME $AGE
dawn 17
[root@CentOS8 ~]#echo $NAME$AGE
dawn17
[root@CentOS8 ~]#echo $NAME_$AGE
17
[root@CentOS8 ~]#echo ${NAME}_$AGE
dawn_17

#变量的间接赋值和引用,ps:原变量的值修改后,被赋值的变量的值不会随之变更
[root@CentOS8 ~]#TITLE=cto
[root@CentOS8 ~]#NAME=dawn
[root@CentOS8 ~]#TITLE=$NAME
[root@CentOS8 ~]#echo $NAME
dawn
[root@CentOS8 ~]#echo $TITLE
dawn
[root@CentOS8 ~]#NAME=haha
[root@CentOS8 ~]#echo $NAME
haha
[root@CentOS8 ~]#echo $TITLE
dawn

#利用变量实现动态命令
[root@CentOS8 ~]#CMD=hostname
[root@CentOS8 ~]#$CMD
CentOS8.dawn

变量的显示和删除

set		显示已定义的所有变量
unset <name>	删除变量name

范例

[root@CentOS8 ~]#NAME=dawn
[root@CentOS8 ~]#TITLE=ceo
[root@CentOS8 ~]#echo $NAME $TITLE
dawn ceo
[root@CentOS8 ~]#unset NAME TITLE
[root@CentOS8 ~]#echo $NAME $TITLE

[root@CentOS8 ~]#

环境变量

  • 可使子进程(子子孙孙进程)继承父进程的变量,但无法让父进程使用子进程的变量
  • 一旦子进程修改从父进程继承的变量,会将新的值传递给孙子进程,不影响父进程的值
  • 一般只在系统配置文件中使用,在脚本使用较少

声明赋值引用

#声明并赋值
export name=VALUE
declare -x name=VALUE

#也可先赋值再声明
name=VALUE
export name

#变量引用
$name${name}

显示所有环境变量

[root@CentOS8 ~]#env
[root@CentOS8 ~]#printenv
[root@CentOS8 ~]#export
[root@CentOS8 ~]#declare -x

删除变量

unset name

只读变量

只能声明定义,后续不能修改和删除,即常量

声明查看

#声明
readonly name  或declare -r name

#查看
readonly [-p]
declare -r

范例

#声明常量PI
[root@CentOS8 ~]#readonly PI=3.1415926
[root@CentOS8 ~]#echo $PI
3.1415926
#无法修改常量
[root@CentOS8 ~]#PI=3.14
-bash: PI: readonly variable
#无法删除
[root@CentOS8 ~]#unset PI
-bash: unset: PI: cannot unset: readonly variable

#退出当前shell,常量就被销毁了
[root@CentOS8 ~]#exit

位置变量

在bash shell 中内置的变量,在脚本代码中调用通过命令行传递给脚本的参数

$1,$2,...$n 	对应第1个,第2个等第n个参数,shift [n]换位置
$0	命令本身,包括路径
$*	传递给脚本的所有参数,全部参数视为一个字符串
$@	传递给脚本的所有参数,每个参数视为独立字符串
$#	传递给脚本的参数的个数
$$	脚本执行的过程ID号

ps:$@ $* 只有在被双引号抱起来的时候才会有差异

清空所有位置变量

set --

范例

[root@CentOS8 script]#cat args.sh 
#!/bin/bash
#********************************************************************
# Author:dawn
# Date:2020-08-08 10:21:18
# FileName:args.sh
# URL:https://blog.csdn.net/xiao_dan_
# Version:1.0
# Description:The test script
#********************************************************************
echo "1st arg is $1"
echo "2st arg is $2"
echo "3st arg is $3"
echo "10st arg is ${10}"
echo "11st arg is ${11}"

echo "\$# The number of arg is $#"
echo "\$* All args are $*"
echo "\$@ All args are $@"
echo "The scriptname is `basename $0`"
echo "\$\$ PID is $$"

[root@CentOS8 script]#bash args.sh {a..z}
1st arg is a
2st arg is b
3st arg is c
10st arg is j
11st arg is k
$# The number of arg is 26
$* All args are 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
$@ All args are 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
The scriptname is args.sh
$$ PID is 3052

范例- @ 和 @ 和 @* 的区别

#$@ 和$* 的区别 --主要用在轮询的时候
[root@CentOS8 script]#cat test.sh
echo "\$* 展示的所有参数:$*"
for i in "$*";do
   echo $i
done

echo "\$@ 展示的所有参数:$@"
for i in "$@";do
    echo $i
done

[root@CentOS8 script]#bash test.sh dawn li 22 33
$* 展示的所有参数:dawn li 22 33
dawn li 22 33
$@ 展示的所有参数:dawn li 22 33
dawn
li
22
33

范例-利用软链接实现同一个脚本不同功能

[root@CentOS8 script]#vim ln.sh
#!/bin/bash
echo $0
#设置软链接
[root@CentOS8 script]#ln -snf ln.sh a.sh
[root@CentOS8 script]#ln -snf ln.sh b.sh

#执行软链接
[root@CentOS8 script]#bash a.sh 
a.sh
[root@CentOS8 script]#bash b.sh 
b.sh

退出状态码变量

在shell 脚本中使用 $? 保存程序执行状态码的相关数字,不同的值反应成功或失败,$? 取值范围在0-255

$?	上一条命令执行后的状态,0:执行正常,非零为异常,一般结果为1

自定义退出状态码
exit [n]	n的取值范围在0-255

范例

[root@CentOS8 ~]#curl http://www.wangxiaochun.com &> /dev/null
[root@CentOS8 ~]#echo $?
0

ps:

  • 脚本中一旦遇到exit 命令,脚本会立即终止;终止退出状态码取决于exit 命令后的数字
  • 如果未给脚本指定退出状态码,整个脚本的退出状态码取决于脚本中执行的最后一条命令的状态码

脚本安全和set

set

可用来定制shell 环境

set 命令实现脚本安全

-u	在扩展一个没有设置的变量时,显示错误信息,等同set -o nounset
-e	如果一个命令返回一个非0退出状态值(失败)就退出,等同set -o errexit
-o	option 显示,打开或关闭选项
	显示选项:set -o
	打开选项:set -o 选项
	关闭选项:set +o	选项
-x	当执行命令时,打印命令及其参数,类似bash -x

范例

[root@CentOS8 ~]#set -o
allexport      	off
braceexpand    	off
emacs          	on
……省略……

$- 变量

h	hashall,打开选项后,shell 会将命令所在的路径hash 下来,避免每次都要查询。通过set +h 将h 选项关闭
i	interactive-comments,包含这个选项说明当前的shell 是一个交互式的shell。所谓交互式shell,在脚本中,i 选项是关闭的
m	moniter,打开监控模式,可通过job control来控制进程的停止、继续,后台或前台执行等
B	braceexpand,大括号扩展
H	history,H选项打开,可展开历史列表的命令,可通过感叹号! 来完成,例如:!! 返回最近一个历史命令,!n 返回第n 个历史命令

范例

[root@CentOS8 ~]#echo $-
himBHs
[root@CentOS8 ~]#echo {1..10}
1 2 3 4 5 6 7 8 9 10
[root@CentOS8 ~]#set +B
[root@CentOS8 ~]#echo $-
himHs
[root@CentOS8 ~]#echo {1..10}
{1..10}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值