Shell 变量
用一个固定的字符串去表示不固定的内容
变量的类型
自定义变量
定义变量
:变量名=变量值
变量名必须以字母或下划线开头,区分大小写(示例: ip1=192.168.2.115 )引用变量
:$变量名
或${变量名}
查看变量
:echo $变量名
或者set
(所有变量:包括自定义变量和环境变量)取消变量
:unset 变量名
作用范围
: 仅在当前Shell中有效
环境变量
export JAVA_HOME=/usr/local/java
- 查看环境变量
env | grep JAVA_HOME
- 环境变量作用范围
- 当前shell和子shell都有效
局部变量
一般用于函数内,表示变量只在当前函数内有效
loacl bak_dir="/data_bak/"
位置变量
$1
、$2
、$3
、$4
、$5
、$6
…
预定义变量
$0
脚本自身的文件名称
$*
所有的参数
"$*"
(带双引号)会将所有的参数作为一个整体,以"$1 $2 … $n"
的形式输出所有参数
$@
所有的参数
"$@"
(带双引号)会将各个参数分开,以"$1"
"$2"
…
"$n"
的形式输出所有参数
$#
参数的个数
$$
当前进程的PID$!
上一个后台进程的PID$?
上一个命令的返回值 0表示成功
变量的赋值方式
显式赋值
- 变量名=变量值
path_dir=$(cd $(dirname $0); pwd) today=$(date +%F)
read 从键盘读入变量值
read 变量名
read -p "提示信息: " 变量名
read -t 5 -p "提示信息: " 变量名
read -n 2 变量名
- read: 用法:read [-ers] [-a 数组] [-d 分隔符] [-i 缓冲区文字] [-n 读取字符数] [-N 读取字符数] [-p 提示符] [-t 超时] [-u 文件描述符] [名称 …]
#!/usr/bin/env bash bak_dir1=/var/backup read -p "请输入您的备份目录: " back_dir2 echo $bak_dir1 echo $bak_dir2
#!/usr/bin/env bash read -p "Please input ipaddress: " ip ping -c2 $ip >& /dev/null if [ $? = 0 ];then echo "host $ip is ok" else echo "host $ip is fail" fi
declare
- 与
typeset
是一样的,都是bash的内建命令,不仅可以定义变量,还可以设定变量的属性
语法格式
-表示设置属性
+表示取消属性
aAfFgilprtux都是具体的选项
declare [+/-] [aAfFgilprtux] [变量名=变量值]
-a
设置变量为索引数组-A
设置变量为关联数组-f
列出之前由用户在脚本中定义的函数名称和函数体-F
仅列出自定义函数名称-g
在函数内创建全局变量-i
设置变量为整数类型
-p
显示指定变量的属性和变量值-r
设置变量为只读(不可删除和修改
),等价于readonly name
-x
设置变量为环境变量,等价于export name=value
定义引用变量
" "
弱引用' '
强引用
#!/usr/bin/env bash my_name=$(whoami) echo "${my_name}" echo '${my_name}'
执行脚本后,就会出现如下的结果
root ${my_name}
在有变量的情况下,强引用不会将变量值传递给变量,而是原封不动的将内容输出出来,所以,强引用表示他本身,在使用过程中,需要注意场景
- ```(反引号) ` 命令替换
- 等价于
$()
- 反引号中的Shell命令会被先执行
变量的运算
整数运算
+
加-
减*
乘(在使用expr的方式时,使用 \* 来表示乘法运算符号
)/
除%
取余数
expr的方式
#!/usr/bin/env bash a=1 b=1 expr ${a} + ${b} expr ${a} - ${b} expr ${a} \* ${b} expr ${a} / ${b} expr ${a} % ${b}
注意: 运算符号前后均有空格
$(( ))的方式
#!/usr/bin/env bash a=1 b=1 echo $((${a}+${b})) echo $((${a}-${b})) echo $(((${a}*${b})+${a})) echo $((${a}/${b})) echo $((${a}%${b}))
二进制转十进制
echo $((2#10011110101110110100010))
十六进制转十进制
echo $((16#4f5da2))
$[ ]的方式
#!/usr/bin/env bash a=1 b=1 echo $[${a}+${b}] echo $[${a}-${b}] echo $[(${a}*${b})+${a}] echo $[${a}/${b}] echo $[${a}%${b}]
let的方式
#!/usr/bin/env bash i=1 let i++ echo ${i}
小数运算
bc命令的方式
+
加-
减*
乘/
除%
取余数^
幂(次方)
#!/usr/bin/env bash a=2 b=10 echo "${a}^${b}" | bc echo "${a}+${b}" | bc echo "${a}*${b}" | bc echo "${a}/${b}" | bc echo "${a}%${b}" | bc
awk的方式
awk 'BEGIN{print 2^10}'
python的方式
echo "print 5.0/2" | python
变量"内容"的删除
#
从前往后匹配
##
从前往后,贪婪匹配
%
从后往前匹配
%%
从后往前匹配,贪婪匹配
.
匹配的字符
*
所有的字符
#!/usr/bin/env bash test_url='www.GoodGoodStudy.DayDayUp.com' echo "标准查看: ${test_url}" echo "变量值的长度: ${#test_url}" echo "从前往后,最短匹配: ${test_url#*.}" echo "从前往后,最长匹配(贪婪匹配): ${test_url##*.}" echo "从后往前,最短匹配: ${test_url%.*}" echo "从后往前,最长匹配(贪婪匹配): ${test_url%%.*}"
结果如下
标准查看: www.GoodGoodStudy.DayDayUp.com 变量值的长度: 30 从前往后,最短匹配: GoodGoodStudy.DayDayUp.com 从前往后,最长匹配(贪婪匹配): com 从后往前,最短匹配: www.GoodGoodStudy.DayDayUp 从后往前,最长匹配(贪婪匹配): www
贪婪匹配就是匹配到指定的字符最后出现的位置,将此字符之前或之后的内容删除
变量"内容"的替换
用法:
变量名称/替换前的内容/替换后的内容
#!/usr/bin/env bash test_url='www.GoodGoodStudy.DayDayUp.com' echo "将com替换为cn: ${test_url/com/cn}" echo "将o替换为O(贪婪匹配): ${test_url//o/O}"
结果如下
将com替换为cn: www.GoodGoodStudy.DayDayUp.cn 将o替换为O(贪婪匹配): www.GOOdGOOdStudy.DayDayUp.cOm
贪婪匹配,其实就是匹配所有(因为全都要,所以才贪婪)
变量的索引以及切片
#!/usr/bin/env bash test_url='www.GoodGoodStudy.DayDayUp.com' echo "从第一个字符开始往后的五个字符的内容: ${test_url:0:5}" echo "从第六个字符开始往后的五个字符的内容: ${test_url:5:5}" echo "切去前五个字符后的内容: ${test_url:5}"
结果如下
从第一个字符开始往后的五个字符的内容: www.G 从第六个字符开始往后的五个字符的内容: oodGo 切去前五个字符后的内容: oodGoodStudy.DayDayUp.com
变量的替换
这里在练习的时候,需要注意,变量值通过
unset
命令清除不了原先的赋值,只需要断开终端,重新连接即可
echo ${var:-新变量值} ; echo ${var} echo ${var:+新变量值} ; echo ${var} echo ${var:=新变量值} ; echo ${var}
变量值为空时
:-aaa
var变量的值会临时被替换为aaa,但var变量自身的值,仍然为空值:+aaa
var变量的值不会临时被替换为aaa,但var变量自身的值,仍然为空值
:=aaa
var变量的值直接被替换为aaa,且永久被替换
变量已被赋值时
var1=111
:-aaa
var1变量的值不会临时被替换为aaa,自身的赋值任然不变:+aaa
var1变量的值不会临时被替换为aaa,自身的赋值任然不变:=aaa
var1变量的值不会临时被替换为aaa,自身的赋值任然不变
:?aaa
var1变量的值不会临时被替换为aaa,自身的赋值任然不变- TA已心有所属,别再馋TA身子了,TA是不会跟你走的
i++与++i的区别
#!/usr/bin/env bash i=1 j=1 let k=i++ let l=++j echo "变量K的值为: ${k}" echo "变量l的值为: ${l}" echo "变量i的值为: ${i}" echo "变量j的值为: ${j}"
结果如下
变量K的值为: 1 变量l的值为: 2 变量i的值为: 2 变量j的值为: 2
i++
先赋值,再运算
++i
先运算,再赋值
对于单纯的变量来说,两者之间没有影响
但是对于表达式而言,最终的变量值是不相同的