shell 变量定义 以及使用
从此刻开始跟我一起学习shell 相关知识吧
前情回顾
上一章节【shell 前奏知识】 我们已经学习了很多shell的必备知识,让我们一起来回顾下。
- shelll的存放位置
- 如何切换shell
- shell文件中的注释有哪些
- 查看当前系统的shell类型
- 执行shell的n种方式
- shell调试的几种方案
- 以及筛选IP 的经典实例
1. 变量分类
那什么是变量分类呢,变量怎么还会分类呢??? 接下来让我们看下分类到底有哪些
- 本地变量
- 全局变量
- shell内置变量
其实都非常简单。
可以将本地变量
比喻成为 我们在js/Java 中手动定义的变量
可以将全局变量
比喻成为 我们在js/ Java中跨作用域的变量
可以将内置变量
比喻成为 哪些不需要我们手动定义,就可以调用的变量,这些变量是语言本身内置的
2. 变量定义
变量定义非常简单,但是有严格的格式要求:变量=值
。 在符号【=】的左右两侧不能有空格。
因为空格在shell中是特殊的命令结束符,会被特殊处理。
例如:
[root@localhost my]# age = 20
-bash: age: command not found
在变量age后面有一个空格,会单独将age
作为一个命令。所以报错。
正确的代码:
[root@localhost my]# echo $name
[root@localhost my]# name=lihh
[root@localhost my]# echo $name
lihh
3. 类型变量定义
此方式比较鸡肋,作为了解即可
命令语法
declare 参数 变量名=变量值
参数解析:
-i 将变量看成整数
-r 使变量只读 readonly,==**该变量的值无法改变,并且不能为unset**==
-x 标记变量为全局变量,类似于export
-a 指定为索引数组(普通数组);查看普通数组
-A 指定为关联数组;查看关联数组
注意:
在生产场景中,这种方法比较鸡肋,使用频率 0-20次/3年
4. 移除变量
通过上述的学习,我们已经学会了在shell中如何定义一个变量。那么变量不可能一直存在,那如果我们想移除怎么办呢
unset 【变量名】
实例
[root@localhost my]# echo $age
[root@localhost my]# age=20
[root@localhost my]# echo $age
20
[root@localhost my]# unset age
[root@localhost my]# echo $age
[root@localhost my]#
5. 单引号以及双引号区分
基本格式
序号 | 样式 | 要点 |
---|---|---|
方式一 | 变量名=变量值 | 变量值必须是一个整体,中间没有特殊字符 “=” 前后不能有空格 |
方式二 | 变量名=‘变量值’ | 原字符输出,我看到的内容,我就输出什么内容, |
方式三 | 变量名=“变量值” | 如果变量值范围内,有可以解析的变量A,那么首先解析变量A, 将A的结果和其他内容组合成一个整体,重新赋值给变量B |
方式一 演示
[root@localhost my]# name=lihh
[root@localhost my]# echo $name
lihh
方式二 演示
[root@localhost my]# name1='name1-$name'
[root@localhost my]# echo $name1
name1-$name
[root@localhost my]#
方式三 演示
[root@localhost my]# name2="name2-$name"
[root@localhost my]# echo $name2
name2-lihh
[root@localhost my]#
6. 命令变量
执行某个命令 将命令的结果赋值给变量
格式
变量=$(命令)
实例
[root@localhost my]# echo $name
[root@localhost my]# name=$(whoami)
[root@localhost my]# echo $name
root
[root@localhost my]#
7. 全局变量
其实无论我们是运维还是开发,我们都需要知道当前系统中有哪些环境变量。 所以掌握如何查找环境变量还是非常重要的
到底有哪些办法呢
查看全局环境变量
env 只显示全局变量,一般结合 grep 和管道符来使用
printenv 效果与env等同
export 查看所有的环境变量,包括声明的过程等信息,一般不用
declare -x 效果与export类似
真实案例
[root@localhost day02]# env
XDG_SESSION_ID=13
HOSTNAME=localhost.localdomain02
SHELL=/bin/bash
TERM=xterm
HISTSIZE=1000
USER=root
那我们如何定义全局变量呢
定义全局变量方法一:
变量=值
export 变量
定义全局变量方法二:(最常用)
export 变量=值
8. 变量作用范围
在Linux系统下 有两个地方可以加载配置文件
- 系统级别
/etc/profile
/etc/profile.d/env_file_name
- 用户级别
~/.bashrc
~/.bash_profile
原则上如果是系统级别的变量,所有的用户都可以看到
但是如果是用户级别的变量的话,用户之间是看不到的
变量的定义在shell中作用域也是不同的。原则上通过export
定义的变量,作用域会一直向子shell中传递。但是如果是普通的变量,子shell是无法使用的
父shell内容
#!/bin/bash
export pName=lihh
export pAge=18
pSex=1
echo "父shell的字段pName名字是:${pName}"
echo "父shell的字段pAge名字是:${pAge}"
echo "父shell的字段pSex名字是:${pSex}"
# 调用子shell
/bin/bash /var/my/day02/cShell
子shell内容
#!/bin/bash
echo "接受父shell的pName是:${pName}"
echo "接受父shell的pAge是:${pAge}"
echo "接受父shell的pSex是:${pSex}"
执行结果
[root@localhost day02]# /bin/bash ./pShell
父shell的字段pName名字是:lihh
父shell的字段pAge名字是:18
父shell的字段pSex名字是:1
接受父shell的pName是:lihh
接受父shell的pAge是:18
接受父shell的pSex是:
[root@localhost day02]#
通过上述结果能看到,父shell中定义的sex,在子shell中并没有打印出来。
9. 内置变量
9.1 脚本相关
脚本相关的变量解析
序号 | 变量名 | 解析 |
---|---|---|
1 | $0 | 获取当前执行的shell脚本文件名 |
2 | $n | 获取当前执行的shell脚本的第n个参数值,n=1…9, 当n为0时表示脚本的文件名,如果n大于9就要用大括号括起来${10} |
3 | $# | 获取当前shell命令行中参数的总个数 |
4 | $? | 获取执行上一个指令的返回值(0为成功,非0为失败) |
9.1.1 $0 获取执行脚本名称
[root@localhost day02]# cat tShell01
#!/bin/bash
# 获取执行脚本的名称
echo "执行脚本的名称是:$0"
[root@localhost day02]# /bin/bash ./tShell01
执行脚本的名称是:./tShell01
[root@localhost day02]# /bin/bash /var/my/day02/tShell01
执行脚本的名称是:/var/my/day02/tShell01
[root@localhost day02]#
9.1.2 $n 获取脚本的参数
[root@localhost day02]# cat tShell02
#!/bin/bash
# 获取执行脚本的参数
echo "第一个参数是:$1"
echo "第二个参数是:$2"
echo "第三个参数是:$3"
echo "第四个参数是:$4"
[root@localhost day02]# /bin/bash ./tShell02 aa bb cc dd
第一个参数是:aa
第二个参数是:bb
第三个参数是:cc
第四个参数是:dd
[root@localhost day02]#
9.1.3 $# 获取脚本参数个数
[root@localhost day02]# cat tShell03
#!/bin/bash
# 获取参数个数
echo "参数个数为: $#"
[root@localhost day02]# /bin/bash ./tShell03
参数个数为: 0
[root@localhost day02]# /bin/bash ./tShell03 aa bb cc
参数个数为: 3
[root@localhost day02]#
9.1.4 $? 返回上一个指令执行结果
[root@localhost day02]# echo name
name
[root@localhost day02]# echo $?
0
[root@localhost day02]# ech
-bash: ech: command not found
[root@localhost day02]# echo $?
127
[root@localhost day02]#
9.2 字符串相关
字符串相关的语法还是比较简单的。
字符串计数
${#file} 获取字符串的长度
字符串截取
- 语法为${var:pos:length} 表示对变量var从pos开始截取length个字符,pos为空标示0
${file:0:5} 从0开始,截取5个字符
${file:5:5} 从5开始,截取5个字符
${file::5} 从0开始,截取5个字符
${file:0-6:3} 从倒数第6个字符开始,截取之后的3个字符
${file: -4} 返回字符串最后四个字节,-前面是"空格"
实例
[root@localhost day02]# address=sfsfsdfsdfsdfsfsdfsgsdgsfafsdassdasdadas
[root@localhost day02]# echo ${address}
sfsfsdfsdfsdfsfsdfsgsdgsfafsdassdasdadas
# 计算字符串长度
[root@localhost day02]# echo ${#address}
40
# 从下标0开始 截取长度为5
[root@localhost day02]# echo ${address:0:5}
sfsfs
# 从下标0开始 截取长度为5
[root@localhost day02]# echo ${address::5}
sfsfs
# 从倒数第6位开始 截取长度为5
[root@localhost day02]# echo ${address:0-6:5}
sdada
# 截取倒数二位
[root@localhost day02]# echo ${address: -2}
as
[root@localhost day02]#
9.3 默认值相关
格式解读
格式一:${变量名:-默认值}
变量a如果有内容,那么就输出a的变量值
变量a如果没有内容,那么就输出默认的内容
格式二:${变量名+默认值}
无论变量a是否有内容,都输出默认值
实例
[root@localhost day02]# cat tShell04
#!/bin/bash
# 测试默认值
age=99
echo "输出默认值:${name:-lihh}"
echo "必须输出的年龄:${age:+18}"
[root@localhost day02]# /bin/bash ./tShell04
输出默认值:lihh
必须输出的年龄:18
[root@localhost day02]#
9.4 其他相关
脚本相关的变量解析
序号 | 变量名 | 解析 |
---|---|---|
1 | $_ | 在此之前执行的命令或脚本的第一个内容 |
2 | $@ | 传给脚本的所有参数 |
3 | $* | 是以一个单字符串显示里所有向脚本传递的参数,与位置参数不同,参数可超过9个 |
4 | $$ | 是脚本运行的当前进程的ID号,作用是方便以后管理它杀掉他 |
5 | $! | 前一条命令进程的ID号,作用是方便以后管理它杀掉他 |