第一部分:Bash变量概述
Shell和其他语言的对比:
1.PHP和Java主要实现功能
2.所见即所得,Shell用于简化管理操作
一、什么是变量与变量分类
1.什么是变量:
变量是计算机内存的单元,其中存放的值可以改变
变量让你能够把程序中准备使用的每一段数据都赋给一个简短易于记忆的名字
2.变量命名规则:
变量名必须以字母或下划线打头,名字中间只能由字母、数字和下划线组成;
变量名的长度不可以超过255个字符;
变量名在有效范围内必须是唯一的;
在Bash中,变量的默认类型都是字符型;
在任何系统中,目录名,文件名,变量名都要有含义;
3.变量按照存储数据分类
字符串型
[[email protected] ~]# a123 = “hello,shell”
整型
浮点型
日期型
4.变量的分类
用户自定义变量:变量自定义的,内容名称作用都可以自定义;
环境变量:这种变量中主要保存的是和紫铜操作环境相关的数据。变量可以自定义的,但是对系统生效的环境变量名和变量作用是固定的,一部分可以自定义;
位置参数变量:这种变量主要是用来向脚本当中传递参数或数据的,变量名不能自定义,变量作用也是固定的,预定义变量的一种,作用单一,数量多;
预定义变量:是Bash中已经定义好的变量,变量名不能自定义,变量作用也是固定的,不可以自己增加,完全系统定义的,只能人为的修改其中的值;
二、用户自定义变量
1.定义变量
变量名=变量值
例如:
x=5
name=”shell”
注:“=”左右不能有空格,加了之后系统觉得你输入的是命令,命令需要用空格隔开;变量名开头必须是下划线或者字母
[[email protected] ~]# x=5 [[email protected] ~]# name=”shell” [[email protected] ~]# 5x=6 -bash: 5x=6: command not found [[email protected] ~]# name = “shell” -bash: name: command not found
单引号与双引号区别:
‘ ‘ :单引号,在单引号中所有的特殊符号,如“$”和“`”和“\”都没有特殊含义
" " :双引号。在双引号中特殊符号都没有特殊含义,但是“$”和“`”和“\”例外拥有
“调用变量的值”,“引用命令”和“转义符”的特殊含义
2.变量的调用
$:用于选取变量所对应得值,如需要调用变量name的值,使用$name的方式就能得到变量的值
echo $变量名#echo适用于输出的命令
例如:
echo $x echo $name
注:Shell和PHP在定义变量上就不一样的:PHP是 $x=5,Shell是x=5;调用时都需要加$x
[[email protected] ~]# echo $x
5#默认定义的是字符型,也就是说这个”5“是字符,而不是数字
[[email protected] ~]# echo $name shell [[email protected] ~]# y=6 [[email protected] ~]# z=$x+$y [[email protected] ~]# echo $z 5+6
3.变量叠加
例如:
x=123 x=”$x”456 x=${x}789
如果只是再次赋值,那么不会出现叠加,而是覆盖:
[[email protected] ~]# x=123 [[email protected] ~]# echo $x 123#这里将不是上面出现的5,也不是5123 [[email protected] ~]# x=”$x”456 [[email protected] ~]# echo $x 123456#叠加,可以使变量做部分修改,特别是变化出现在末尾 [[email protected] ~]# x=${x}789 [[email protected] ~]# echo $x 123456789
4.变量查看
[[email protected] ~]# set
选项:
-u 如果设定此选项,调用未声明变量时会报错(默认无任何提示)
[[email protected] ~]# echo $a
[[email protected] ~]#
#上面出现的一个空值,有两种:一是没有定义该变量,二是该变量本来就是空值,那我们应该怎么区分呢?
[[email protected] ~]# set –u [[email protected] ~]# echo $a -bash: a: unbound variable [[email protected] ~]#
5.变量删除
[[email protected] ~]# unset 变量名 [[email protected] ~]# unset name #上面变量名前不要加取值符$ [[email protected] ~]# unset name [[email protected] ~]# echo $name -bash: name: command not found
三、环境变量
1.环境变量与用户自定义变量的区别:
环境变量是全局变量,用户自定义变量是局部变量;也就是说在当前shell和这个shell的所有子shell中都生效,而用户自定义变量只能是当前shell才能生效
2.设置环境变量
export 变量名=变量值:就是在用户自定义变量前加一个export
或者
变量名=变量值
export变量名
[[email protected] ~]# export z=1 [[email protected] ~]# bash [[email protected] ~]# pstree sshd---bash---bash—pstree
3.查看环境变量
(1).set
#查看所有变量,包括环境变量
(2).env
#查看环境变量,只查看环境变量
4.调用变量
echo $变量名
5.删除变量
unset 变量名,注意删除环境变量需要回到父shell,不允许在子shell中删除,会提示报错
[[email protected] ~]# unset $z bash: unset : `1’:not a valid identifier [[email protected] ~]# exit exit [[email protected] ~]# unset $z [[email protected] ~]# pstree --sshd---bash---pstree
变量可以自定义,但是对系统生效的环境变量名和变量作用都是固定的,它们会影响操作系统的操作环境
6.常用系统变量
HOSTNAME:主机名
SHELL:当前shell
TERM:终端环境
HISTSIZE:历史命令条数
SSH_CLIENT:当前操作环境是用ssh连接的,这里记录客户端ip
#SSH_CLIENT=192.168.0.155 2408 22
SSH_TTY:ssh连接的终端时pts/1
#SSH_TTY=/dev/pts/0
USER: 当前登录的用户
#USER=root
区分环境变量和命令:环境变量用大写,命令全小写
(1).PATH变量:系统查找命令的路径
echo $PATH
#查看PATH环境变量
PATH=”$PATH“:/root/sh
#增加PATH变量的值
当我们敲一个命令的时候,可以使用绝对路径或者相对路径,但你会发现我们其实都是不敲路径的,而PATH的作用就是使我们能够直接使用命令进行运行
[[email protected] ~]# vi hello.sh #/bin/bash echo “shell is beautiful” ~ ~ wq [[email protected] ~]# chmod 755 hello.sh [[email protected] ~]# ./hello.sh shell is beautiful [[email protected] ~]# /root/hello.sh shell is beautiful
现在我想把hello.sh让它和ls命令一样可以直接运行:
[[email protected] ~]# cp hello.sh /bin/ [[email protected] ~]# hello.sh #(可以按TabTab补全)
我们可以通过变量叠加来添加环境变量到PATH
[[email protected] ~]# PATH=”@PATH”:/root [[email protected] ~]# echo $PATH [[email protected] ~]# hello.sh shell is beautiful
7.PS1环境变量
PS1变量:命令提示符设置
\d:显示日期,格式为”星期 月 日“
\H:显示完整的主机名。如默认主机名为”localhost.localdomain“
\t:显示24小时制时间,格式为”HH:MM:SS“
\A:显示24小时制时间,格式为”HH:MM"
\u:显示当前用户名user
\w:显示当前所在目录的完整名称
\W:显示当前所在目录的最后一个目录
\$:提示符。如果是root用户就会显示提示符为"#“,如果是普通用户会显示提示符为”$“
[[email protected] ~]# echo $PS1 [\[email protected]\h \W]\$ [[email protected] ~]# 与[\[email protected]\h \W]\$一一对应
下面我们进行一些修改:
[[email protected] ~]# cd /usr/local/src [[email protected] src]# PS1=’[\[email protected]\A \w]\$ ’ [[email protected]:22 /usr/local/src]#
上面的提示符设置格式只在当前命令行生效,如果需要永久生效,需要写入到指定位置
虽然DIY是可以的,但是你会觉得原来的更顺眼
[[email protected]:22 /usr/local/src]# PS1=’[\[email protected]\h \W]\$ ’ [[email protected] src]#
补充:当自己敲一条代码太长的时候,可以有\来进行换行:
[[email protected] ~]# ls > [[email protected] ~]#
8.当前语系查询及语系变量LANG
locale
#查询当前系统语系
-LANG:定义系统主语系的变量
-LC_ALL:定义整体语系的变量
echo $LANG
#查看系统当前语系,系统已经生效的语系,重启后不一定生效
locale –a | more
#查看linux支持的所有语系
cat /etc/sysconfig/i18n
#查询系统默认语系
[[email protected] ~]# cat /etc/sysconfig/i18n
LANG=”zh_CN.UTF-8”
这格式重启后仍可以生效的语系
Linux中文支持:
前提条件,正确安装了中文字体和中文语系,可以有以下结果:
如果有图形界面,可以正确支持中文显示
如果有使用第三方远程工具,只要语系设定正确,可以支持中文显示
如果使用纯字符界面,必须使用第三方插件(如zhcon等)
四、位置参数变量
1.位置参数变量:
位置参数变量 | 作用 |
$n | n为数字,$0代表命令本身,$1-$9代表从第一到第九个参数,十以上的参数需要用大括号包含,如${10},传递需要的值 |
$* | 这个变量代表命令行所有的参数,$*把所有的参数看成一个整体,参数间用空格隔开,但依旧认为是一个整体 |
[email protected] | 这个变量也代表命令行所有的参数,不过[email protected] 把每个参数区分对待 |
$# | 这个变量代表命令行中所有参数的个数 |
例子1:$n功能实现
定义参数:
[[email protected] ~]# mkdir sh [[email protected] ~]# cd sh [[email protected] sh]# ls [[email protected] sh]# touch sum.sh [[email protected] sh]# vi sum.sh #!/bin/bash sum1=$((10+20)) echo $sum1 num1=$1 num2=$2 sum=$(($num1+$num2))
#变量sum的和是num1和num2加起来的和的数值所传递过去的
echo $sum
#打印变量sum的值
调用参数:
[[email protected] sh]# chmod 755 sum.sh [[email protected] sh]# ./sum.sh 30 [[email protected] sh]# ./sum.sh 45 67 30 112
#可以在脚本后面添加两个数直接添加参数值,一般只适用于自己,毕竟自己调用的,第三方#很难知道其功能的使用
例子2:$* ,[email protected],$*功能实现
#!/bin/bash
echo “A total of $# parameters”
#使用$#代表所有参数的个数
echo “The parameters is: $*”
#使用$*代表所有的参数
echo “The parameters is: [email protected]”
#使用[email protected]也代表所有参数
[[email protected] sh]# touch parameters.sh [[email protected] sh]# vi parameters.sh #!/bin/bash echo “\$* The parameters is: $*” echo “\[email protected] The parameters is : [email protected]” echo “\$# A total of :$# ” wq [[email protected] sh]# chmod 755 parameters.sh [[email protected] sh]# ./parameters.sh 11 22 33 44 $* The parameter is : 11 22 33 44 [email protected] The parameters is : 11 22 33 44 S# A total of :4
例子3:$*与[email protected]区别
[[email protected] sh]# touch for.sh [[email protected] sh]# vi for.sh #!/bin/bash for i in “$*”
#$*中所有参数看成一个整体,所以这个for循环只会循环一次
do echo “The parameters is: $i” done for y in “[email protected]” #[email protected] 中的每个参数都看成是独立的,所以”[email protected]“中有几个参数就会循环几次 do echo “Parameter: $y” done wq [[email protected] sh]# chmod 755 for.sh [[email protected] sh]# ./for.sh 1 2 3 4 5 1 2 3 4 5 1 2 3 4 5 [[email protected] sh]#
五、预定义变量
1.预定义变量:
预定义变量 | 作用 |
$? | 最后一次执行命令的返回状态,如果这个变量的值为0,证明上一个命令的值正确执行;如果这个变量的值为非0(具体是哪个数由命令自己决定),则证明上一个命令执行错误 |
$$ | 当前进程的进程号(PID) |
$! | 后台运行的最后一个进程的进程号(PID) |
例子1:区分$?返回值
[[email protected] sh]# ls [[email protected] sh]# echo $? 0 [[email protected] sh]# ls app ls:无法访问app: 没有那个文件或目录 [[email protected] sh]# echo $? 2 [[email protected] sh]# app -bash :app: command not found [[email protected] sh]# echo $? 127
其实返回值0,2,127,$?的返回值由人为确定的
其实这运用到了shell里的:&&,||,前者是前面的命令成功,后面才能运行;后者是前面的命令失败了,后面才能运行。其中运用的就是echo $?,0与非0
[[email protected] sh]# echo $$ 2911 [[email protected] sh]# ps aux | grep 2911 root 2911 0.0 0.1 6824 1720 pts/0 Ss 21:36 0:00 -bash root 3114 0.0 0.0 5960 744 pts/0 S+ 22:36 0:00 grep 2911 [[email protected] sh]# vi bl.sh #!/bin/bash echo “Now : $$” find /root –name hello.sh & echo “houtai : $!” ~ wq [[email protected] sh]# chmod 755 bl.sh [[email protected] sh]# ./bl.sh Now :3137 houtai:3138
#返回的是当前脚本后台运行时进程的PID,所以是3119而不是2911
#&:后台符
2.接收键盘输入
read [选项] [变量名]
选项:
-p ”提示信息“:在等待read输入的时候,输出提示信息
-t 秒数 :read命令会一直等待用户输入,使用此选项可以指定等待时间
-n 字符数:read 命令只接收指定的字符数,就会执行
-s :隐藏输入的数据,适用于机密信息的输入
[[email protected] sh]# vi read.sh #!/bin/bash read –p “please input your name: ”-t 30 name echo $name echo –e “\n”#重新打印一下,并自动换行 read –p “please input your age: ”-s age echo –e “\n” read –p “please input your sex[M/F]:”-n 1 sex ~ wq [[email protected] sh]# chmod 755 read.sh [[email protected] sh]# ./read.sh please input your name: DukeZ DukeZ
#允许输入提示信息
#-t 30的单位是30秒
[
[email protected] sh]# chmod 755 read.sh [[email protected] sh]# ./read.sh please input your name: DukeZ DukeZ please input your age: 20 please input your sex [M/F]: M M
第二部分:Shell编程运算符
一、概述及declare命令
Shell变量缺点:
弱类型
默认字符串型
1.declare命令:
用于声明变量类型:
[[email protected] ~]# declare [+/-][选项] 变量名
选项:
-:给变量设定类型属性
+:取消变量的类型属性
-a:将变量声明为数组型
+a:取消声明变量为数组型
-i:将变量声明为整数型(integer)
-x:将变量声明为环境变量
-r:将变量声明为只读变量(read)
-p:显示指定变量的被声明的类型
例子:将变量声明为数值型
[[email protected] ~]# aa=11 [[email protected] ~]# bb=22 #给aa和bb赋值 [[email protected] ~]# cc=$aa+$bb [[email protected] ~]# echo $cc 11+22 [[email protected] ~]# declare –i cc=$aa+$bb
#声明变量cc的类型是整数型,它的值是aa和bb的和,不用把aa,bb提前声明
[[email protected] ~]# echo cc 33 [[email protected] ~]# declare –p -i
2.声明数组变量
#定义数组
[[email protected] ~]# movie[0]=zp [[email protected] ~]# movie[1]=tp [[email protected] ~]# declare –a movie[2]=live
#查看数组
[[email protected] ~]# echo ${movie} [[email protected] ~]# echo ${movie[2]} [[email protected] ~]# echo ${movie[*]}
例子:
[[email protected] ~]# movie[0]=a [[email protected] ~]# movie[1]=b [[email protected] ~]# declare –a movie[2]=c [[email protected] ~]# echo ${movie}
a#未指定下标的话默认是第一个,即movie[0]
[[email protected] ~]# echo ${movie[2]} c [[email protected] ~]# echo ${movie[*]}
a b c #所有的数组都会显示
3.声明环境变量
declare –x test=123
#和export作用相似,但其实是declare命令的作用
声明成环境变量后才能在子shell内显示
与export作用类似,但是export是declare –x [变量名]的简化命令,最终执行的命令其实就是declare命令
4.声明变量只读属性
[[email protected] ~]# declare –r test
#给test赋予只读属性,但是请注意只读属性会让变量不能修改不能删除,甚至不能取消只读属性(毕竟不能执行)
例子:
[[email protected] ~]# declare –x test=123 [[email protected] ~]# declare –p test declare –x test=”123” [[email protected] ~]# declare –r test [[email protected] ~]# declare –p test declare –rx test=”123” [[email protected] ~]# test=456 -bash: test: readonly variable [[email protected] ~]# unset test -bash: unset: test: cannot unset: readonly variable [[email protected] ~]# declare +r test -bash: declare: test:readonly variable
二、数值运算方法
方法很多,选择自己习惯,自己喜欢的就好了。
1.数值运算方法1:
[[email protected] ~]# aa=11 [[email protected] ~]# bb=22
#给aa和bb赋值
[[email protected] ~]# declare –i cc=$aa+$bb
#声明变量cc的类型是整数型,它的值是aa和bb的和,不用把aa,bb提前声明
[[email protected] ~]# echo cc 33
2.数值运算方法2:expr或let数值运算工具
[[email protected] ~]# aa=11 [[email protected] ~]# bb=22
#给变量aa和变量bb赋值
[[email protected] ~]# dd=$(expr $aa + $bb)
#dd的值是aa和bb的和。注意“+号左右两侧必须有空格”
[[email protected] ~]# echo dd 33 [[email protected] ~]# ee=$(expr $aa+$bb) [[email protected] ~]# echo ee 11+22
#注意要用空格隔开“+”左右两边
3.数值运算方法3:“$((运算式))”或“$[运算式]”
[[email protected] ~]# aa=11 [[email protected] ~]# bb=22
#给变量aa和变量bb赋值
[[email protected] ~]# ff=$(($aa+$bb)) 33 [[email protected] ~]# gg=$[$aa+$bb] 33
#这里的$[]会和后面的条件测试语句混淆,建议使用双小括号
#hh=$()是吧括号里的结果赋值给hh
[[email protected] ~]# hh=$(date) [[email protected] ~]# echo hh 2015年 08月 02日 星期日 13:26:34 CST [[email protected] ~]# ii=date [[email protected] ~]# echo $ii date
4.运算符:
优先级 | 运算符 | 说明 |
13 | -,+ | 单目负、单目正 |
12 | !,` | 逻辑非、按位取反或补码 |
11 | * , / , % | 乘、除、取模 |
10 | + , - | 加、减 |
9 | << , >> | 按位左移、按位右移 |
8 | <=,>=,<,> | 小于或等于、大于或等于、小于、大于 |
7 | == , != | 等于、不等于 |
6 | & | 按位与 |
5 | ^ | 按位异或 |
4 | | | 按位或 |
3 | && | 逻辑与 |
2 | || | 逻辑或 |
1 | = , += , *= , /= , %= , &= , `= , |= , <<= , >>= | 赋值、运算且赋值 |
注:这里是优先级数值高的优先级高
例子:
[[email protected] ~]# aa=$(((11+3)*3/2)) [[email protected] ~]# echo $aa 21
#虽然乘和除的优先级高于加,但是通过小括号可以调整运算符优先级
[[email protected] ~]# bb=$((14%3)) [[email protected] ~]# echo $bb 2
#14不能被3整除,余数是2
[[email protected] ~]# cc=$((1&&0)) [[email protected] ~]# echo $cc 0
#逻辑与运算只有相与的两边都是1,与的结果才是1,否则与的结果是0(同1为1)
[[email protected] ~]# dd=$((1||0)) [[email protected] ~]# echo dd 1
#逻辑或只要有1,或的结果就是1(有1为1)
三、变量测试
通用度不高,只应用与Shell,格式比较复杂,但是语法简单
变量置换方式 | 变量y没有设置 | 变量y为空值 | 变量y设置值 |
x=${y-新值} | x=新值 | x为空 | x=$y |
x=${y:-新值} | x=新值 | x=新值 | x=$y |
x=${y+新值] | x为空 | x=新值 | x=新值 |
x=${y:+新值} | x为空 | x为空 | x=新值 |
x=${y=新值} | x=新值 y=新值 |
x为空 y值不变 |
x=$y y值不变 |
x=${y:=新值} | x=新值 y=新值 |
x=新值 y=新值 |
x=$y y值不变 |
x=${y?新值} | 新值输出到标准错误输出(屏幕) | x为空 | x=$y |
x=${y:?新值} | 新值输出到标准错误输出(屏幕) | 新值输出到标准错误输出(屏幕) | x=$y |
变量测试在脚本优化时使用,程序压力小,用PHP追求效率,但是会比较复杂,但是shell适用于自动化,需要逻辑简单
例子1:测试x=${y-新值}
[[email protected] ~]# unset y #删除变量y [[email protected] ~]# x=${y-2} #进行测试 [[email protected] ~]# echo x 2 #因为变量y不存在,所以x=new [[email protected] ~]# y=”” [[email protected] ~]# set … y= [[email protected] ~]# x=${y-2} [[email protected] ~]# echo $x #也是空值 [[email protected] ~]# y=1 [[email protected] ~]# x=${y-2} [[email protected] ~]# echo x 1
测试命令能看懂即可,了解就可以了