目录
变量的定义
变量:bash作为程序设计语言和其他高级语言一样也提供使用和定义变量的功能,简单说就是让一个特定的字符串代表不固定的内容 a=123,echo $a。在shell中变量不能永久存在,必须在文件中声明。
变量的类型
预定义变量、环境变量、自定义变量、位置变量
自定义变量
自定义变量:即使自己设置的变量,只能在当前终端和脚本中使用
变量名称=值
变量:变量名称只能由字母,数字,下划线组成,不能以数字开头。注意:应该让变量名称有意义
=:赋值符号,前后不能有空格
值:所有的字符串和数字都可以
引用变量:$变量名或${变量名}
临时变量,仅当前终端可用
[root@nfy ~]# a=123
[root@nfy ~]# echo ${a}
123
[root@nfy ~]# echo $a
123
查看变量:echo $变量名
取消变量:unset 变量名
环境变量
环境变量:shell在开始执行时已经定义好的,就是系统执行环境的一些设置
定义环境变量的方法:
1、export back_dir2=/home/backup
2、export back_dir1 将自定义变量换成环境变量
引用环境变量:$变量名或${变量名}
查看环境变量:echo $变量名
取消环境变量:unset 变量名
变量作用范围: 在当前shell和zishell有效
环境变量拥有可继承性:export之后就拥有继承性环境变量可以被向下继承,可用unset取消。
永久生效:写到四个登录脚本,/etc/profile、~/.baserc、~/.bash_profile 、/etc/bashrc
/etc/profile
这是系统最主要的shell设置文件,也是用户登陆是系统最先检查的文件,有关重要的环境变量都定义在此,其中包括PATH,USER,LOGBAME,HOSTNAME,HISTNAME,HISTSIZE,INPUTRC等。而在文件的最后,它会检查并执行/etc/profile.d/*.sh的脚本。
~/.bash_profile
这个文件是每位用户的bash环境设置文件,它存在与于用户的主目录中,当系统执行/etc/profile 后,就会接着读取此文件内的设置值。在此文件中会定义USERNAME,BASH_ENV和PATH等环境变量,但是此处的PATH除了包含系统的$PATH变量外加入用户的“bin”目录路径。
~/.bashrc
接下来系统会检查~.bashrc文件,这个文件和前两个文件(/etc/profile 和~.bash_profile)最大的不同是,每次执行bash时,~.bashrc都会被再次读取,也就是变量会再次地设置,而/etc/profile,~./bash_profile只有在登陆时才读取。就是因为要经常的读取,所以~/.bashrc文件只定义一些终端机设置以及shell提示符号等功能,而不是定义环境变量。
~/.bash_login
如果~/.bash_profile文件不存在,则系统会转而读取~/.bash_login这个文件内容。这是用户的登陆文件,在每次用户登陆系统时,bash都会读此内容,所以通常都会将登陆后必须执行的命令放在这个文件中。
.profile
如果~./bash_profile ~./bash_login两个文件都不存在,则会使用这个文件的设置内容,其实它的功能与~/.bash_profile相同。
.bash_logout
如果想在注销shell前执行一些工作,都可以在此文件中设置。
~/.bash_history
这个文件会记录用户先前使用的历史命令。
PATH:这个变量存放的是所有命令所在的路径 修改:PATH=$PATH:+目录
意义:让所有命令在执行的时候不必输入路径
位置变量
位置变量也叫位置参数:在脚本代码中调用通过命令行传递给脚本的参数。
$1 $2 $3 $... #分别对应传递给脚本内容里面的第1、第2等参数
[root@linux-server ~]# cd /opt/test/script/
[root@linux-server script]# vim weizhi.sh
#!/usr/bin/bash
echo 我的第一个位置参数是:$1
echo 我的第二个位置参数是:$2
echo 我的第三个位置参数是:$3
echo 我的第四个位置参数是:$4
echo 一共有 $# 个位置参数
echo 你输入的参数分别是:$*
[root@linux-server script]# chmod +x weizhi.sh
[root@linux-server script]# ./weizhi.sh 1 3 4 6
我的第一个位置参数是:1
我的第二个位置参数是:3
我的第三个位置参数是:4
我的第四个位置参数是:6
一共有 4 个位置参数
你输入的参数分别是:1 3 4 6
预定义变量
预定义的特殊变量有着特殊的含义,用户不可以更改,所有的预定义变量都由$符号和另外一个符号组成,常用的预定义特殊变量如下:
$$ 当前进程PID
$? 命令执行后的返回状态:0 为执行正确,非 0 为执行错误
$# 位置参数的数量
$* 所有位置参数的内容
$@ 显示所有的参数
$! 上一个后台进程的PID (wait命令中使用)
[root@linux-server ~]# echo $? 最后一次执行的命令的返回状态。如果这个变量的值为 0,则证明上一条命令正确执行;如果这个变量的值为非 0 ,则 证明上一条命令执行错误
[root@linux-server ~]# echo $$ 当前进程的进程号(PID)
[root@linux-server ~]# echo $! 后台运行的最后一个进程的进程号(PID)
变量的赋值方式
变量的赋值方式有五种:直接赋值、使用read命令赋值、使用命令行参数进行赋值、使用命令的输出结果进行赋值、从文件中读取
直接赋值(显式赋值)
变量名=变量值
ip1=192.168.1.251
school="BeiJing 1000phone"
today1=`date +%F`
today2=$(date +%F)
[root@nfy ~]# echo ${ip1}
192.168.1.251
read从键盘读入变量值
read命令用于从标准输入读取数值。read内部命令被用来从标准输入读取单行数据,这个命令可以用来读取键盘输入,当使用重定向的时候,可以读取文件中的一行数据。
语法:read 【options】变量名
options:常用参数详解
-a:后面跟一个变量,该变量会被认为是个数组,然后给其赋值,默认是以空格为分隔符
-p:后面跟提示信息,在输入前打印提示信息
-t:后面跟秒数,定义输入字符的等待时间
-s:在输入字符时不再屏幕上显示
-n:后面跟一个数字,定义输入文本的长度,很实用
-e:在输入时可以使用命令补全功能
示例
#!/bin/bash
read -s -p "Enter your password: " pass -p提示信息 -s在输入时不显示字符
echo "your password is $pass" $pass 引用变量
exit 4 退出并返回一个值
[root@nfy shell]# bash readtest3.sh
Enter your password: your password is 123
[root@nfy shell]# echo $?
4
使用命令行参数进行赋值
使用位置参数
#/bin/bash
a=$1
b=$2
c=$3
echo "三个位置参数: $1 $2 $3 "
echo "输出变量a,b,c的值为:$a,$b,$c"
[root@nfy shell]# bash b.sh 1 2 3
三个位置参数: 1 2 3
输出变量a,b,c的值为:1,2,3
使用环境变量
#/bin/bash
basedir=/root/xtrabackup
export basedir
echo ${basedir}
# 或者
export basedir1=/root/xtrabackup/full
echo ${basedir1}
[root@nfy shell]# bash b.sh
/root/xtrabackup
/root/xtrabackup/ful
使用命令的输出结果进行赋值
#/bin/bash
a=`cat /etc/hosts|awk 'NR==1 {print $1}'`
echo $a
[root@nfy shell]# bash b.sh
127.0.0.1
从文件中读取
#/bin/bash
while read line
do
hosts[++i]=$line
数组 索引付值 读取的内容
数组名 下标(索引) 值
done</etc/hosts
for i in ${!hosts[*]} #遍历数组
do
echo "$i:${hosts[$i]}"
done
[root@nfy shell]# bash b.sh
1:127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
2:::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
定义或引用变量时注意事项:
" " 弱引用 可以实现变量和命令的替换
' ' 强引用 不完成变量替换
[root@xingdian ~]# school=1000phone
[root@xingdian ~]# echo "${school} is good"
1000phone is good
[root@xingdian ~]# echo '${school} is good'
${school} is good
` ` 命令替换 等价于 $() 反引号中的shell命令会被先执行
[root@xingdian ~]# touch `date +%F`_file1.txt
[root@xingdian ~]# touch $(date +%F)_file2.txt
[root@xingdian ~]# disk_free3="df -Ph |grep '/$' |awk '{print $4}'" 错误
[root@xingdian ~]# disk_free4=$(df -Ph |grep '/$' |awk '{print $4}')
[root@xingdian ~]# disk_free5=`df -Ph |grep '/$' |awk '{print $4}'`
变量的运算
整数运算
运算命令 | 含义 |
(()) | 用于整数运算 |
$[ ] | 用于整数运算 |
let | 用于整数运算,类似(()) |
expr | 用于整数运算,功能较多 |
运算符
符号 | 含义 |
+,- | 加,减 |
*,/,% | 乘,除,取余 |
** | 幂数运算 |
++,– | 自增,自减 |
=,+=,-=,*=, /=, %= | 复制运算 |
<, <=, >, >= | 比较符号 |
方法一:expr
[root@nfy shell]# a=111
[root@nfy shell]# expr $a + 123 # $a,+,123 之间必须都有空格
234
[root@nfy shell]# expr $a - 110
1
[root@nfy shell]# expr $a * 2 #这里需要转义符,让*变为原来的意思
expr: 语法错误
[root@nfy shell]# expr $a \* 2 # 转义符
222
[root@nfy shell]# expr $a / 111
1
[root@nfy shell]# expr $a % 10 #取余
1
方法二:$[ ]
[root@nfy shell]# a=10
[root@nfy shell]# echo $[a-1]
9
[root@nfy shell]# echo $[a+1]
11
[root@nfy shell]# echo $[a*1] 这里*不需要转义
10
[root@nfy shell]# echo $[a/1]
10
[root@nfy shell]# echo $[a%3]
1
方法三:$(())
[root@nfy shell]# a=100
[root@nfy shell]# echo $((a+1))
101
[root@nfy shell]# echo $((a-1))
99
[root@nfy shell]# echo $((a*1)) *也不需要转义
100
[root@nfy shell]# echo $((a/1))
100
[root@nfy shell]# echo $((a%3))
1
方法四:let
let命令在执行后会保存新的值
[root@nfy shell]# a=10
[root@nfy shell]# let a+=10
[root@nfy shell]# echo $a # 查看a的值时,a的值变成了20
20
[root@nfy shell]# let a-=5
[root@nfy shell]# echo $a # a的值变为15
15
[root@nfy shell]# let a*=10
[root@nfy shell]# echo $a # a的值变为150
150
[root@nfy shell]# let a/=10
[root@nfy shell]# echo $a # a的值变为15
15
[root@nfy shell]# let a%=10
[root@nfy shell]# echo $a # a的值变为5
5
随机数RANDOM(扩展)
利用RANDOM这个随机数生成器进行取余就能够实现。取余时需要+1,因为在取余时如果被整除那么余数会是0,这样就不在限定范围内了。
[root@nfy shell]# echo $RANDOM
5748
[root@nfy shell]# echo $(($RANDOM % 6 + 1))
5
[root@nfy shell]# echo $(($RANDOM % 6 + 1))
6
[root@nfy shell]# echo $(($RANDOM % 6 + 1))
2
[root@nfy shell]# echo $(($RANDOM % 10 + 1))
1
[root@nfy shell]# echo $(($RANDOM % 10 + 1))
4
[root@nfy shell]# echo $(($RANDOM % 10 + 1))
10
匹配删除
[root@xingdian ~]# url=www.sina.com.cn
[root@xingdian ~]# echo ${#url} 获取变量值的长度
15
[root@xingdian ~]# echo ${url} 标准查看
www.sina.com.cn
[root@xingdian ~]# echo ${url#*.} 从前往后,最短匹配
sina.com.cn
[root@xingdian ~]# echo ${url##*.} 从前往后,最长匹配 贪婪匹配
cn
[root@xingdian ~]# url=www.sina.com.cn
[root@xingdian ~]# echo ${url}
www.sina.com.cn
[root@xingdian ~]# echo ${url%.*} 从后往前,最短匹配
www.sina.com
[root@xingdian ~]# echo ${url%%.*} 从后往前,最长匹配 贪婪匹配
www
[root@xingdian ~]# url=www.sina.com.cn
[root@xingdian ~]# echo ${url#a.} 错误写法
www.sina.com.cn
[root@xingdian ~]# echo ${url#*sina.}
com.cn
[root@xingdian ~]# echo $HOSTNAME
xingdian.1000phone.com
[root@xingdian ~]# echo ${HOSTNAME%%.1*}
xingdian
索引及切片
[root@xingdian ~]# url=www.sina.com.cn
[root@xingdian ~]# echo ${url:0:5}
0:从头开始
5:到第五个
[root@xingdian ~]# echo ${url%%.s*}
www
[root@xingdian ~]# echo ${url:0:5}
www.s
[root@xingdian ~]# echo ${url:5:5}
ina.c
[root@xingdian ~]# echo ${url:5}
ina.com.cn
"内容"的替换
[root@xingdian ~]# url=www.sina.com.cn
[root@xingdian ~]# echo ${url/sina/baidu}
www.baidu.com.cn
[root@xingdian ~]# url=www.sina.com.cn
[root@xingdian ~]# echo ${url/n/N}
www.siNa.com.cn
[root@xingdian ~]# echo ${url//n/N} 贪婪匹配
www.siNa.com.cN
变量的替代
[root@nfy shell]# unset var1
[root@nfy shell]# echo ${var1} 变量未赋值
[root@nfy shell]# echo ${var1-aaaaa} 使用"-"
aaaaa 返回了新的值,但不等于把默认值赋值给该变量
[root@nfy shell]# echo ${var1} 可以看到该变量的值仍是空
[root@nfy shell]# var2=111 变量被赋值
[root@nfy shell]# echo ${var2-bbbbb} 返回变量本来的值
111
[root@nfy shell]# var3= 变量的值为空
[root@nfy shell]# echo ${var3-ccccc} 返回值为空
[root@nfy shell]# unset var1
[root@nfy shell]# unset var2
[root@nfy shell]# unset var3 var1未赋值
[root@nfy shell]# var2= var2赋值为空
[root@nfy shell]# var3=111 var3赋值不为空
[root@nfy shell]# echo ${var1:-aaaa} 返回新的值,但不等于把默认值赋值给var1
aaaa
[root@nfy shell]# echo ${var1} 可以看到变量var1的值仍是空
[root@nfy shell]# echo ${var2:-aaaa} 返回新的值,但不等于把默认值赋值给var2
aaaa
[root@nfy shell]# echo ${var2} 可以看到变量var2的值仍是空
[root@nfy shell]# echo ${var3:-aaaa} 返回变量本来的值
111
[root@nfy shell]# echo ${var3+aaaa} 返回新的值,但不等于把默认值赋值给var3
aaaa
[root@nfy shell]# echo ${var3} 可以看到变量var3的值仍是111
111
[root@nfy shell]# echo ${var3:+aaaa} 返回新的值,但不等于把默认值赋值给var3
aaaa
[root@nfy shell]# echo ${var3} 可以看到变量var3的值仍是111
111
[root@nfy shell]# echo ${var3=aaaa} 返回变量原本的值
111
[root@nfy shell]# echo ${var3}
111
[root@nfy shell]# echo ${var3:=aaaa} 返回变量原本的值
111
[root@nfy shell]# echo ${var3}
111
[root@nfy shell]# echo ${var3?aaaa} 返回变量原本的值
111
[root@nfy shell]# echo ${var3:?aaaa} 返回变量原本的值
111
(1)${parameter:-word}
若 parameter 为空或未设置,返回默认值但是并不把默认值赋值给该变量,若 parameter 不为空,则不替换,parameter 的值不变(2) ${parameter:=word}
若 parameter 为空或未设置,把默认值赋值给该变量。若 parameter设置了,则不替换,parameter的值不变(3) ${parameter:+word}
若 parameter 不为空时,返回默认值,并且也不重新赋值。
i++ 和 ++i (了解)
i++是自增运算,规则是先运算在let i++
[root@xingdian ~]# echo $i自增,每次自增的步距为1
对变量的值的影响:
[root@xingdian ~]# i=1
[root@xingdian ~]# let i++
[root@xingdian ~]# echo $i
2
[root@xingdian ~]# j=1
[root@xingdian ~]# let ++j
[root@xingdian ~]# echo $j
2
对表达式的值的影响:
[root@xingdian ~]# unset i
[root@xingdian ~]# unset j
[root@xingdian ~]#
[root@xingdian ~]# i=1
[root@xingdian ~]# j=1
[root@xingdian ~]#
[root@xingdian ~]# let x=i++ 先赋值,再运算
[root@xingdian ~]# let y=++j 先运算,再赋值
[root@xingdian ~]#
[root@xingdian ~]# echo $i
2
[root@xingdian ~]# echo $x
1
[root@xingdian ~]# echo $j
2
[root@xingdian ~]# echo $y
2