关于变量的内容
一、变量命名:
二、变量赋值:
三、变量类型:
四、变量取消:
五、取得变量值:
六、调整变量的属性
七、数组
八、变量扩展:
九、命令扩展:
一、变量名称:
1、只能包含字母、数字和下划线,并且不能以数字开头,
2、不应该跟系统中已有的环境变量重名
3、最好能见名知意
二、变量赋值:
设置变量:
变量名称=值
var_name=value 等号两边不能有空格
[root@lovelace 51cto]
# youname=lovelace
[root@lovelace 51cto]
# echo $youname
lovelace
针对数字,你可以可以这样为变量赋值,定义一个变量的类型
[root@lovelace 51cto]
# declare -i sum=100
[root@lovelace 51cto]
# echo $sum
100
三、bash:变量类型:
环境变量:
本地变量(局部变量):
位置变量:
特殊变量(系统变量):
本地变量:作用域为整个bash进程
varname=value
局部变量:作用域只对当前代码段有效
local varname=value
环境变量:作用域为当前shell进程及其子进程
export varname=value "导出“
任意脚本在执行时会启动一个子shell进程,
命令行中启动的脚本会继承当前shell的环境变量
系统自动执行的脚本(跟命令行无关)就需要自我定义需要的各环境变量
位置变量:
$1,$2,....
特殊变量:保持某些特殊数据
$? 上一个命令执行状态返回值
$# 参数的个数
$* 参数列表
$@ 参数列表
$0 命令本身 脚本本身
执行脚本时的脚本路径及名称
程序执行一般有两类返回值
程序执行结果;
执行状态返回代码(0-255)
0表示正确
1-255:错误执行 1,2,127 系统预留 有特殊意义
四、撤销变量:
unset varname
1
[root@lovelace 51cto]
# unset youname;echo $youname
查看当前shell中的变量
set 不带任何参数和选项
[root@lovelace 51cto]
# set
BASH=
/bin/bash
BASH_ARGC=()
BASH_ARGV=()
BASH_LINENO=()
BASH_SOURCE=()
BASH_VERSINFO=([0]=
"3"
[1]=
"2"
[2]=
"25"
[3]=
"1"
[4]=
"release"
[5]=
"i386-redhat-linux-gnu"
)
BASH_VERSION=
'3.2.25(1)-release'
COLORS=
/etc/DIR_COLORS
.xterm
COLUMNS=80
CVS_RSH=
ssh
DIRSTACK=()
EUID=0
GROUPS=()
G_BROKEN_FILENAMES=1
HISTFILE=
/root/
.bash_history
HISTFILESIZE=5000
HISTSIZE=5000
HOME=
/root
HOSTNAME=lovelace.localdomain
HOSTTYPE=i386
IFS=$
' \t\n'
INPUTRC=
/etc/inputrc
LANG=zh_CN.GB2312
LC_ALL=zh_CN.GB2312
LESSOPEN=
'|/usr/bin/lesspipe.sh %s'
LINES=20
LOGNAME=root
LS_COLORS=
'no=00:fi=00:di=00;34:ln=00;36:pi=40;33:so=00;35:bd=40;33;01:cd=40;33;01:or=01;05;37;41:mi=01;05;37;41:ex=00;32:*.cmd=00;32:*.exe=00;32:*.com=00;32:*.btm=00;32:*.bat=00;32:*.sh=00;32:*.csh=00;32:*.tar=00;31:*.tgz=00;31:*.arj=00;31:*.taz=00;31:*.lzh=00;31:*.zip=00;31:*.z=00;31:*.Z=00;31:*.gz=00;31:*.bz2=00;31:*.bz=00;31:*.tz=00;31:*.rpm=00;31:*.cpio=00;31:*.jpg=00;35:*.gif=00;35:*.bmp=00;35:*.xbm=00;35:*.xpm=00;35:*.png=00;35:*.tif=00;35:'
MACHTYPE=i386-redhat-linux-gnu
MAIL=
/var/spool/mail/root
MAILCHECK=60
OLDPWD=
/home/scripts
OPTERR=1
OPTIND=1
OSTYPE=linux-gnu
PATH=
/usr/kerberos/sbin
:
/usr/kerberos/bin
:
/usr/local/sbin
:
/usr/local/bin
:
/sbin
:
/bin
:
/usr/sbin
:
/usr/bin
:
/root/bin
PIPESTATUS=([0]=
"0"
)
PPID=16933
PROMPT_COMMAND=
'printf "\033]0;%s@%s:%s\007" "${USER}" "${HOSTNAME%%.*}" "${PWD/#$HOME/~}"'
PS1=
'[\u@\h \W]\$ '
PS2=
'> '
PS4=
'+ '
PWD=
/home/scripts/51cto
SHELL=
/bin/bash
SHELLOPTS=braceexpand:emacs:hashall:histexpand:
history
:interactive-comments:monitor
SHLVL=1
SSH_ASKPASS=
/usr/libexec/openssh/gnome-ssh-askpass
SSH_CLIENT=
'192.168.2.28 8577 22'
SSH_CONNECTION=
'192.168.2.28 8577 192.168.2.54 22'
SSH_TTY=
/dev/pts/0
SUPPORTED=zh_CN.UTF-8:zh_CN.GBK:zh_CN.GB2312:zh_CN:zh:en_US.UTF-8:en_US:en
TERM=xterm
UID=0
USER=root
_=
echo
consoletype=pty
sum
=100
tmpid=0
x=101
如果查看当前shell中的环境变量
env
export
printenv
字符串变量添加新的变量
PATH添加新的路径
export PATH=$PATH:/usr/local/apsch/bin
五、取得变量值:
$变量名称
${变量名称} $(x) 这个可以用来当做命令调用
如果变量在语句当中被引用,必须要使用${x}才可以,取得数组的变量值时候也需要使用${}来调用
[root@lovelace 51cto]
# listnum=100
[root@lovelace 51cto]
# echo $listnum
100
[root@lovelace 51cto]
# echo ${listnum}
100
关于变量和引号的关系:
单引号:所见即所得
双引号:使特殊符号生效
[root@lovelace 51cto]
# echo "There are $listnum pelple."
There are 100 pelple.
[root@lovelace 51cto]
# echo 'There are $listnum pelple.'
There are $listnum pelple.
六、调整变量的属性:
1、readonly 命令 :定义只读变量
-p:显示目前具有只读属性的变量列表
-f:设定函数不可修改
-a:定义数组不可修改
2、declare 命令
-r:设定只读变量
-p:显示变量的属性
-a:变量是一个数组
-f:搜寻命令时,只找函数
-i:变量是一个整数
-F:显示所有的函数式名称及其属性
-t:设立变量具有trace属性
-x:设定环境变量
七、 数组:
是一种数据结构,有相关的数据项组成,每个数据项,称为数组的元素,且可采用索引的方式取得个元素的值
数组赋值:
1、单个赋值,以index作为索引号,索引号从0开始
a[0]=1
a[2]=2
a[3]=3
#为数组赋值
[root@lovelace 51cto]
# a[0]=1
[root@lovelace 51cto]
# a[1]=2
[root@lovelace 51cto]
# a[2]=3
#显示数组中所有值方法一
[root@lovelace 51cto]
# echo ${a[*]}
1 2 3
#显示数组中所有值方法二
[root@lovelace 51cto]
# echo ${a[@]}
1 2 3
#为数组添加数据项
[root@lovelace 51cto]
# a[3]='nick'
[root@lovelace 51cto]
# echo ${a[*]}
1 2 3 nick
2、使用小括号为数组赋值
a=(1 2 3) 默认空格隔开
#为数组b赋值 记住是小括号,不是大括号
[root@lovelace 51cto]
# b=(bbs www http ftp)
[root@lovelace 51cto]
# echo ${b[*]}
bbs www http
ftp
#打印出第一个和第三个数据项
[root@lovelace 51cto]
# echo ${b[0]};echo '*******';echo ${b[2]}
bbs
*******
http
3、为数组中的某一个数据项赋值,默认是从0开始,如果中间出现未比标示的索引项,则从前一个索引项开始计算
a={51 [3]=5 cto [6]=8}
#为数组赋值
[root@lovelace 51cto]
# c=(51cto [3]='nick' 51 [5]='lovelace')
#打印出数组中所有值
[root@lovelace 51cto]
# echo ${c[@]}
51cto nick 51 lovelace
#验证中间出现的数值是从哪个索引项开始算起的
[root@lovelace 51cto]
# echo ${c[1]}
[root@lovelace 51cto]
# echo ${c[0]}
51cto
[root@lovelace 51cto]
# echo ${c[2]}
[root@lovelace 51cto]
# echo ${c[4]}
51
显示赋值:
echo ${a[1]}
取出数组中所有的值:
echo ${a[@]} 或者echo ${a[*]}
取得数组元素的个数:
echo ${#a[@]} 或者 echo ${#a[*]}
#打印出数组所有值,统计数组中数据项个数
[root@lovelace 51cto]
# echo ${c[@]};echo ${#c[@]};echo ${#c[*]}
51cto nick 51 lovelace
4
八、高级变量:
${变量名称} 变量扩展
$(命令) 命令替换
$((算术式)) 算术扩展
$(命令) 命令替换:
测试变量存在与否:
${myname:-'nick'} 判断条件,如果myname存在,就返回值,如果myname不存在,就把-后接的字符串当做整个变量扩展的结果,并传回
测试变量不存在或为空,传回一个默认值
${myname:-'nick'} 如果待测变量不存在或为空,传回-后的值,存在则传回变量的值
测试变量不存在或为空,给变量设定一个默认值
${count:=100} 若变量coutn没有值或为空,则把待测变量设定为默认值,
测试变量不存在或为空,传回错误信息
${myname:?"your input error"}
测试变量的存在性:
${myname:+Ture} 若变量存在且值非空,则符合判断
: 空 测空置
- 负向 测不存在
+ 正向 测存在
? 有问题 检查是否完备后再来执行吧
= 设值 给控值变量设定一个默认值
$(命令) 命令替换 此命令等同于・・ (esc下的按键,不是单引号)这个在编写脚本的时候很有用
#打印出当前路径
[root@lovelace 51cto]
# echo $(pwd)
/home/scripts/51cto
[root@lovelace 51cto]
# echo `pwd`
/home/scripts/51cto
$((算术式))算术扩展:这个我们在下章将会单独讲解,这里给出示例查看
[root@lovelace 51cto]
# a=3;b=5
[root@lovelace 51cto]
# echo $((a+b))
九、变量扩展“去字符串切片,字符串长度
字符串切片是从0开始的 在使用${}的时候 大括号内的变量引用前面的$可以不写
${变量:位置起点} ${myname:3}
${变量:位置起点:长度}
#定义变量
[root@lovelace 51cto]
# myname=lovelace
#取得变量字符串从第三个字符开始到字符串结尾的所有字符
[root@lovelace 51cto]
# echo ${myname:3}
elace
#取得变量字符串中从第四个字符开始,长度为2的字符
[root@lovelace 51cto]
# echo ${myname:4:2}
la
取部分参数:
命令行参数是从$1开始的依次类推,$@代表所有参数,命令本身使用$0来表示
${@:起点}:由点开始,取得后面的所有的位置参数
${@:起点:个数}:由起点开始,取得指定个数的位置参数
示例脚本
#!/bin/bash
#Verson:0.1
#Auther:lovelace
#Pragram:test argument
#取得程序名
echo
$0
#取得变量的所有值
echo
${@:1}
#取得变量的个数
echo
$
#
执行结果:
[root@lovelace 51cto]
# ./argument.sh 12 32 45
.
/argument
.sh
12 32 45
3
计算字符串长度:
${#变量名称}:传回变量值的字符串长度
expr:也可以统计字符串的长度
1、str="here you are."
len$(expr length "$str")
echo "str 字符串长度是:$len"
2、expr "字符串“:‘。*’
str="here you are."
len=$(expr "$str":'.*')
echo "str字符串长度是:$len"
[root@lovelace 51cto]
# echo $myname
lovelace
#使用${#变量名}取得字符串长度 比较常用
[root@lovelace 51cto]
# echo ${#myname}
8
#使用${expr length “$变量名”}取得字符串长度
[root@lovelace 51cto]
# len=$(expr length "$myname")
[root@lovelace 51cto]
# echo $len
8
#使用${expr “$变量名” : '.*'}取得字符串长度
[root@lovelace 51cto]
# len=$(expr "$myname" : '.*')
[root@lovelace 51cto]
# echo $len
8
变量扩展:对比样式
由字符串前面对比,删除最短的
${变量#样式}
由字符串前面对比,删除最长的
${变量##样式}
#定义一个变量
[root@lovelace 51cto]
# path=$(pwd)
#查看变量值
[root@lovelace 51cto]
# echo $path
/home/scripts/51cto
#使用对比样式
[root@lovelace 51cto]
# echo ${path#*/}
home
/scripts/51cto
#此对比样式可以取得目录名
[root@lovelace 51cto]
# echo ${path##/*/}
51cto
由字符串后面对比,删除最短的
${变量%样式}
由字符串后面对比,删除最长的
${变量%%样式}
#使用此对比样式可以取得路径名
[root@lovelace 51cto]
# echo ${path%/*}
/home/scripts
#使用此对比样式没有任何数据输出
[root@lovelace 51cto]
# echo ${path%%/*}
至于对比样式可以根据自己的思考来获得,这个没有固定的格式
取代或删除部分字符串:
只替换第一个对比符合的字符串
${变量/样式/替换字符串}
替换所有符合的字符串
${变量//样式/替换字符串}
#定义一个变量
[root@lovelace 51cto]
# echo $myname
lovelace
#替换第一次出现的l为F
[root@lovelace 51cto]
# echo ${myname/l/F}
Fovelace
#替换字符串中所有l为F
[root@lovelace 51cto]
# echo ${myname//l/F}
FoveFace
删除对比符合的字符串
只删一个
${变量/样式/}
删除全部
${变量//样式/}
#T 行首位置
%LE 最后面
#定义一个变量获取IP地址相关的信息
[root@lovelace 51cto]
# tmp=$(ifconfig eth0 | grep 'inet addr')
#删除对比样式成功的字符串 然后赋值给变量r
[root@lovelace 51cto]
# r=${tmp/inet addr:/}
#删除对比样式成功的字符串 然后赋值给变量ip
[root@lovelace 51cto]
# ip=${r/ Bcast*/}
#打印出变量ip 查看是不是我们想要的结果
[root@lovelace 51cto]
# echo $ip
192.168.2.54
变量扩展:取变量名称列表、数组索引列表
取变量名称列表:
${!开头字符串@}或${!开头字符串*}
[root@lovelace 51cto]
# myname=lovelace;mytest=51cto
[root@lovelace 51cto]
# echo ${!my@}
myname mytest
[root@lovelace 51cto]
# echo ${!my*}
myname mytest
取数组索引列表:
${!数组变量[@]}或${!数组变量[*]}
#取得数组a的所有值
[root@lovelace 51cto]
# echo ${a[@]}
hello 2 3 nick
#取得数组a的索引项
[root@lovelace 51cto]
# echo ${!a[@]}
0 1 2 3
后记:学习shell编程,变量这一块很重要,文章中列出的仅仅是变量内容的一部分,还有很多像系统内置变量,以及环境变量,局部变量之间的转化,我们这里没有提及到,所以需要我们多练习、多总结。就算你一下记不住这么多知识,熟能生巧总是可以的吧......