设为首页 收藏本站
查看: 1085|回复: 0

shell浅谈之一变量和引用

[复制链接]

尚未签到

发表于 2015-10-26 08:44:33 | 显示全部楼层 |阅读模式

一、简介


         变量是脚本语言的核心,shell脚本又是无类型的。变量本质上存储数据的一个或多个计算机内存地址,分为本地变量(用户当前shell生命期使用,随shell进程的消亡而无效,类似局部变量)、环境变量(适用于所有由登录进程所产生的子进程)和位置参数(向shell脚本传递参数,只读)。而shell使用变量就需要引用,它们密切相关。




二、详解


1、变量赋值      


  (1)变量赋值规则:等号两边不能有空格、value值包括空格必须用双引号、变量名只能包括字母数字和下画杠,并变量名不能以数字开头。
  (2)如果value值中有空格,需要用双引号引以来。variable="hello world"。
  (3)unset命令清除变量的值。
  (4)变量赋值模式
   DSC0000.jpg
  (5)readonly将变量设置为只读,只读变量不能再次进行赋值操作。
   DSC0001.jpg
  

2、无类型的变量
  
  (1)C中定义变量需要声明整型、浮点型、字符型等,而shell脚本变量却是无类型的。shell不支持浮点型只支持整型和字符型,同时字符型还具有一个整型值0(判断标准:变量中只包含数字是数值型其他是字符串)。
  

#!/bin/bash
a=2009
let "a+=1"
echo "a=$a"
b=xx09
echo "b=$b"
declare -i b
echo "b=$b"
let "b+=1"
echo "b=$b"
exit 0 DSC0002.jpg

(2)位置参数  
  从命令行向shell脚本传递参数,$0表示脚本的名字,$1代表第一个参数,以此类推。从${10}开始参数号需要用花括号括起来。
  

#!/bin/sh
echo "The script name is: $0"            #$0表示脚本本身
echo "Parameter #1:$1"
echo "Parameter #2:$2"
echo "Parameter #3:$3"
echo "Parameter #4:$4"
echo "Parameter #5:$5"
echo "Parameter #6:$6"
echo "Parameter #7:$7"
echo "Parameter #8:$8"
echo "Parameter #9:$9"
echo "Parameter #10:${10}"           #用大括号括起来
echo "-------------------------"
echo "All the command line parameters are: $*"特殊的位置参数:  
   DSC0003.jpg
  

3、内部变量

内部变量指能够对bash shell脚本行为产生影响的变量,属于环境变量的范畴。
  
  (1)BASH
        BASH记录了shell的路径,通常是/bin/bash。内部变量SHELL是通过BASH的值确定当前Shell的类型,linux使用的是bash shell,因而两个变量的值都是/bin/bash。


  (2)BASH_VERSINFO
  它是一个包含6个元素的数组,这些元素用于表示bash的版本信息。
  

#!/bin/bash
for n in 0 1 2 3 4 5
do
echo "BASH_VERSINFO[$n]=${BASH_VERSINFO[$n]}"
done DSC0004.jpg
  
  BASH_VERSINFO[0]表示bash shell的主版本号,BASH_VERSINFO[1]表示shell的次版本号,BASH_VERSINFO[2]表示shell的补丁级别,BASH_VERSINFO[3]表示shell的编译版本,BASH_VERSINFO[4]表示shell的发行状态,BASH_VERSINFO[5]表示shell的硬件架构。
  (3)BASH_VERSION
  linux系统的bash shell版本包含主次版本、补丁级别、编译版本和发行状态,即BASH_VERSINFO数组取值为0~4。显示BASH_VERSION的值。
   DSC0005.jpg


  (4)DIRSTACK

      它显示目录栈的栈顶值。linux目录栈用于存放工作目录,便于程序员手动控制目录的切换,bash shell定义了两个系统命令pushd(将某目录压入目录栈并将当前工作目录切换到入栈的目录)和popd(将栈顶目录弹出并将当前工作目录切换到栈顶目录)来维护目录栈。

        DIRSTACK记录栈顶目录值,初值为空。linux还有一个命令dirs用于显示目录栈的所有内容。


  (5)GLOBIGNORE
       它是由冒号分隔的模式列表,表示通配时忽略的文件名集合。一旦GLOBIGNORE非空,shell会将通配得到的结果中符合GLOBIGNORE模式中的目录去掉。例如ls a*列出当前目录以a开头的文件,设置GLOBIGNORE=“ar*”,再次执行ls a*将剔除以ar开头的文件。
  (6)GROUPS
        GROUPS记录了当前用户所属的群组,linux的一个用户可同时包含在多个组内,GROUPS是一个数组记录了当前用户所属的所有群组号。管理用户组的文件是/etc/group,格式:群组名:加密后的组口令:群组号:组成员,组成员(组成员列表)。
  (7)HOSTNAME


        HOSTNAME记录了主机名,linux主机名是网络配置时必须要设置的参数,可在/etc/sysconfig/network文件中设置主机名。/etc/hosts文件用于设定IP地址和主机名之间的对应关系,可快速从主机名查找IP地址。
  (8)HOSTTYPE和MACHTYPE
  都用于记录系统的硬件架构,它们与BASH_VERSINFO[5]等值


DSC0006.jpg


  (9)OSTYPE
  记录操作系统类型,linux系统中,$OSTYPE=linux。
  (10)REPLY
        REPLY变量与read和select命令有关。read用于读取标准输入(stdin)的变量值,read variable将标准输入存储到variable变量中,而read将读到的标准输入存储到REPLY变量中。
       select脚本:
  

#!/bin/bash
echo "Pls. choose your profession?"
select var in "Worker" "Doctor" "Teacher" "Student" "Other"
do
echo "The \$REPLY is $REPLY."  
echo "Your preofession is $var."
break
done DSC0007.jpg

”#?"提示符由shell提示符变量PS3进行设置(#?是其默认值)。修改export PS3="your choice:"。REPLY变量值为用户选择的序号,var变量为REPLY序号所对应的字符串。  
  (11)SECONDS
  SECONDS记录脚本从开始执行到结束所耗费的时间(单位为秒)。调试性能时比较有用。
  

#!/bin/bash
count=1
MAX=5
while [ "$count" -le "$MAX" ];do
echo "This is the $count time to sleep."
let count=$count+1
sleep 1
done
echo "The running time of this script is $SECONDS" DSC0008.jpg

(12)SHELLOPTS  
  它记录了处于开状态的shell选项列表,它是一个只读变量。Shell选项用于改变Shell的行为,Shell选项有开和关两种状态,set命令用于打开或关闭选项。set -o optionname(打开名为optionname选项),set +o optionname(关闭名为optionname选项)。比如打开interactive(交互模式运行)可以使用set -o interactive或set -i等价。Shell选项有很多。
   DSC0009.jpg
  (13)SHLVL
         记录Shell嵌套的层次,启动第一个shell时,$SHLVL=1,若在这个Shell中执行脚本,脚本中的SHLVL为2,脚本中再执行子脚本,SHLVL就会递增。
  (14)TMOUT
  用于设置Shell的过期时间,TMOUT不为0时,shell会在TMOUT秒后将自动注销,TMOUT放在脚本中可以规定脚本的执行时间。
  

#!/bin/bash
TMOUT=3
echo "What is your name?"
read fname
if [ -z "$fname" ]; then
fname="(no answer)"
fi
echo "Your name is $fname" DSC00010.jpg

用户有输入,脚本执行read后的程序,用户没有输入等待TMOUT秒后执行read后程序但fname会为空。
4、有类型变量
      Shell变量一般是无类型的,bash shell提供了declare和typeset两个命令用于指定变量的类型(它们完全等价)。declare [选项] 变量名,有6个选项。
   DSC00011.jpg
  declare命令-r选项将变量设置成只读属性,与readonly命令一样,变量值不允许修改。
  declare命令-x选项将变量声明为环境变量,相当于export,但declare -x允许声明环境变量同时给变量赋值,而export不支持。


  declare -i将变量定义为整型数,不能再按字符串形式处理改变量(和let命令进行算术运算一样,expr命令可以替换let命令)。
  

#!/bin/bash
variable1=2009
variable2=$variable1+1
echo  "variable2=$variable2"
let variable3=$variable1+1
echo  "variable3=$variable3"
declare -i variable4
variable4=$variable1+1
echo  "variable4=$variable4" DSC00012.jpg

      再介绍一种变量执行算术运算的方法:双圆括号即((...))格式。result=$((var1*var2));var1和var2执行乘法运算。双圆括号也可以使shell实现C语言风格的变量操作。  
  

#!/bin/bash
((a = 2014))
echo "The initial value of a is:$a"
((a++))
echo "After a++,the value of a is:$a"
((++a))
echo "After ++a,the value of a is:$a"
((a--))
echo "After a--,the value of a is:$a"
((--a))
echo "After --a,the value of a is:$a" DSC00013.jpg
  
        双圆括号实现五种C语言风格的运算,自增自减是shell算术运算符中未曾定义过的,是C语言中的相关内容。a = 2014,C语言允许赋值两端有空格但shell不允许。双圆括号还可以实现更加复杂的C语言的运算如逻辑判断、三元操作等。


  

5、间接变量引用

      该引用不是将变量引起来,而是理解为:如果第一个变量的值是第二个变量的名字,从第一个变量引用第二个变量的值就称为间接变量引用。bash shell提供了两种格式实现间接变量引用:eval tempvar=\$$variable和tempvar=${!variable},其中eval是关键字,用\$$形式得到variable的简介引用,用${!...}得到variable的间接引用。

  
  

#!/bin/bash
variable1=variable2
variable2=Hadoop
echo "varialbe1=$variable1"
eval tempvar=\$$variable1
echo "tempvar=$tempvar"
echo "Indirect ref variable1 is :${!variable1}" DSC00014.jpg

例:使用间接变量引用实现数据库表格的查找:  
  

#!/bin/bash
S01_name="Li Hao"
S01_dept=Computer
S01_phone=025-83481010
S01_rank=5
S02_name="Zhang Ju"
S02_dept=English
S02_phone=025-83466524
S02_rank=8
S03_name="Zhu Lin"
S03_dept=Physics
S03_phone=025-83680010
S03_rank=3
PS3='Pls. select the number of student:'
select stunum in "S01" "S02" "S03"
do
name=${stunum}_name
dept=${stunum}_dept
phone=${stunum}_phone
rank=${stunum}_rank
echo "BASIC INFORMATION OF NO.$stunum STUDENT:"
echo "NAME:${!name}"
echo "DEPARTMENT:${!dept}"
echo "PHONE:${!phone}"
echo "RANK:${!rank}"
break
done      在间接变量引用中,第一个变量中存放的是最终值的地址,因此,间接变量引用使得shell编程实现了类似于C语言中指针的功能,在很多场合能够精简shell脚本。
  

6、引用


  (1)引用指将字符串用引用符号引起来,以防止特殊字符被shell脚本重解释为其他意义。shell中定义了四种引用符号。

DSC00015.jpg   
  (2)双引号和单引号
         双引号引用除美圆符号($)、反引号(`)和反斜线(\)之外的所有字符,即$和`及\在双引号中仍被解释为特殊意义,利用双引号引用变量能防止字符串分割,而保留变量中的空格。因此双引号的引用方式称为部分引用。
   DSC00016.jpg


          单引号中字符除单引号本身之外都解释为字面意义,不再具备引用变量的功能,单引号的引用方式称为全引用。
  

#!/bin/bash
echo "Why can't I write 's between single quotes"
echo 'Why can'"'"'t I write' "'"'s between single quotes'(3)反引号  
  反引号进行命令替换(将命令的标准输出作为值赋给某个变量),等价于$(),同时$()形式的命令替换是可以嵌套的。如`pwd`和$(pwd)等价都为当前工作目录。


   DSC00017.jpg
  反引号与$()在处理双反斜线时存在区别,反引号将反斜线符号处理为空格,而$()符号将其处理为单斜线符。
   DSC00018.jpg




7、转义
  (1)反斜线符号(\)表示转义,将屏蔽下一个字符的特殊意义,而以字面意义解析它。
   DSC00019.jpg


  

#!/bin/bash
variable="(]\\{}\$\""
echo $variable
echo "$variable"
IFS='\'
echo $variable
echo "$variable"
exit 0 DSC00020.jpg

(2)转义符除了屏蔽特殊字符的特殊意义外,加上一些字母能够表达特殊的含义。  
   DSC00021.jpg
  

#!/bin/bash
#echo不加e选项,按照字面含义解释\t等特殊符号
echo "\t\n\a\v"
#echo加上e选项后,按照特殊含义解释这些特殊符号
echo -e "\t\t\t\thello"
echo $'\t\thello'
echo -e "hello\v\v\v\vhello"
echo -e "\a\a\a\a"
echo -e "\042" DSC00022.jpg
  
  $''与-e选项等价
  (3)echo加-n选项表示输出文字后不换行,不带-n默认是输出文本后自动换行。




三、总结

  (1)从shell的基础开始了解,一步步向上走。
  (2)可发邮件沟通,相互提高!邮箱地址yang.ao@i-soft.com.cn。



版权声明:本文为博主原创文章,未经博主允许不得转载。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-130777-1-1.html 上篇帖子: 用shell脚本实现监控程序自动重启 下篇帖子: C程序获取shell脚本命令输出,使用popen()函数
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表