设为首页 收藏本站
查看: 1217|回复: 1

[经验分享] Shell变量的子串应用技术实践详解

[复制链接]
累计签到:32 天
连续签到:1 天
发表于 2016-5-24 16:31:36 | 显示全部楼层 |阅读模式

shell变量是一种很“弱”的变量,默认情况下,一个变量保存一个串,shell不关心这个串是什么含义。所以若要进行数学运算,必须使用一些命令例如let、declare、expr、双括号等。shell变量可分为两类:局部变量和环境变量。局部变量只在创建它们的shell中可用。而环境变量则可以在创建它们的shell及其派生出来的任意子进程中使用。有些变量是用户创建的,其他的则是专用shell变量。变量名必须以字母或下划线字符开头。其余的字符可以是字母、数字(0~9)或下划线字符。任何其他的字符都标志着变量名的终止。名字是大小写敏感的。给变量赋值时,等号周围不能有任何空白符。为了给变量赋空值,可以在等号后跟一个换行符。用set命令可以查看所有的变量,unset var命令可以清除变量var,var相当于没有定义过。readonly var可以把var变为只读变量,定义之后不能对var进行任何更改。对shell变量的引用方式很多,用这些方式可以方便的获取shell变量的值,变量值的长度,变量的一个字串,变量被部分替换后的值等等。shell变量常见引用方式如下:

2012102200180475.jpg

2012102200182063.jpg

2012102200184126.jpg

2 环境变量
环境变量的定义方法如下:
var=value
export var
shell在初始化的时候会在执行profile等初始化脚本,脚本中定义了一些环境变量,这些变量会在创建子进程时传递给子进程。
用env命令可以查看当前的环境变量。常用的系统环境变量如下:
_(下划线) 上一条命令的最后一个参数
BASH 展开为调用bash实例时使用的全路径名
CDPATH cd命令的搜索路径。它是以冒号分隔的目录列表,shell通过它来搜索cd命令指定的目标目录。例如.:~:/usr
EDITOR 内置编辑器emacs、gmacs或vi的路径名
ENV 每一个新的bash shell(包括脚本)启动时执行的环境文件。通常赋予这个变量的文件名是.bashrc。
EUID 展开为在shell启动时被初始化的当前用户的有效ID
GROUPS 当前用户所属的组
HISTFILE 指定保存命令行历史的文件。默认值是~/.bash_history。如果被复位,交互式shell退出时将不保存命令行历史
HISTSIZE 记录在命令行历史文件中的命令数。默认是500
HOME 主目录。未指定目录时,cd命令将转向该目录
IFS 内部字段分隔符,一般是空格符、制表符和换行符,用于由命令替换,循环结构中的表和读取的输入产生的词的字段划分
LANG 用来为没有以LC_开头的变量明确选取的种类确定locale类
OLDPWD 前一个工作目录
PATH 命令搜索路径。一个由冒号分隔的目录列表,shell用它来搜索命令,一个普通值为 /usr/gnu/bin:/usr/local/bin:/usr/ucb:/usr/bin
PPID 父进程的进程ID
PS1 主提示符串,默认值是$
PS2 次提示符串,默认值是>
PS3 与select命令一起使用的选择提示符串,默认值是#?
PS4 当开启追踪时使用的调试提示符串,默认值是+。追踪可以用set –x开启
PWD 当前工作目录。由cd设置
RANDOM 每次引用该变量,就产生一个随机整数。随机数序列可以通过给RANDOM赋值来初始化。如果RANDOM被复位,即使随后再设置,它也将失去特定的属性
REPLY 当没有给read提供参数时设置
SHELL 当调用shell时,它扫描环境变量以寻找该名字。shell给PATH、PS1、PS2、MAILCHECK和IFS设置默认值。HOME和MAIL由login(1)设置
SHELLOPTS 包含一列开启的shell选项,比如braceexpand、hashall、monitor等
UID 展开为当前用户的用户ID,在shell启动时初始化
3 数值变量
shell中默认把变量值当作字符串,例如:
age=22
age=${age}+1
echo ${age}
输出结果为22+1,而不是23,因为shell将其解释为字符串,而不是数学运算。
可以用let命令使其进行数学运算,例如:
let age=${age}+1
也可以用declare把变量定义为整型。例如:
declare -i age=22
这里就用 -i 选项把age定义为整型的了。此后每次运算,都把age的右值识别为算术表达式或数字。
4 数组
在shell中可以使用数组,例如:
array[0]=0
array[1]=1
array[2]=2
则array就是一个数组,也可以这样给数组初始化:
array=(0 1 2) // 元素之间以空格分隔
可以通过 ${array[$i]}来访问array中某个元素,${array

  • } 的返回值即数组的所有元素组成的串,${#array
  • } 的返回值即数组的元素个数,${array
  • :0:2} 返回第一个和第二个元素组成的串。0表示开始的位置,2表示要返回的元素个数,开始位置可以为0-2(0减去2)之类的,表示从倒数第二个元素开始。
    下面写个稍微复杂点的例子:

    [url=] copycode.jpg [/url]
    1 #!/bin/bash2 for ((i=0; i<<SPAN style="PADDING-BOTTOM: 0px; LINE-HEIGHT: 1.5 !important; MARGIN: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; FONT-FAMILY: 微软雅黑, 宋体; COLOR: rgb(128,0,128); FONT-SIZE: 12px !important; PADDING-TOP: 0px">100; i++))3 do4 array[$i]=$i5 done6 for ((i=0; i<<SPAN style="PADDING-BOTTOM: 0px; LINE-HEIGHT: 1.5 !important; MARGIN: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; FONT-FAMILY: 微软雅黑, 宋体; COLOR: rgb(128,0,128); FONT-SIZE: 12px !important; PADDING-TOP: 0px">100; i++))7 do8 echo ${array[$i]}9 done[url=] copycode.jpg [/url]

    如果要使用二维数组甚至三维数组该怎么实现呢,那就需要用eval命令来模拟数组的功能了。
    eval命令的作用是扫描命令两次再执行,如果不使用eval,只扫描一次,然后执行。看个例子:
    root@suse:~$ name=Barry
    root@suse:~$ $name=hello
    Barry=hello: command not found
    为什么第二句给Barry变量赋值会出错呢?从报错信息可以发现shell并没有识别这是个赋值语句,而是把Barry=hello当作一个命令来执行,当然会报错。为什么不能识别这是赋值语句呢?第一次扫描时,因为扫描到$符号,所以不能把这句当作赋值语句,赋值语句的左边总是一个变量名,而不应该是$开头的。所以第一次扫描仅仅识别了$name变量,并做了替换,而并没有认识到赋值语句。
    如果使用eval $name=hello呢?
    root@suse:~$ name=Barry
    root@suse:~$ $name=hello
    Barry=hello: command not found
    root@suse:~$ eval $name=hello
    root@suse:~$ echo $Barry
    hello
    可见使用了eval之后,对 $name=hello 第一次扫描替换了$name,没有识别赋值语句,第二次扫描识别是赋值语句,然后执行。现在大约可以想到怎样用eval实现二维数组了。
    下面实现的二维数组每一行代表一个人的信息记录,包括姓名,年龄。

    [url=] copycode.jpg [/url]
    1 for ((i=0; i<<SPAN style="PADDING-BOTTOM: 0px; LINE-HEIGHT: 1.5 !important; MARGIN: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; FONT-FAMILY: 微软雅黑, 宋体; COLOR: rgb(128,0,128); FONT-SIZE: 12px !important; PADDING-TOP: 0px">2; i++)) 2 do 3 for ((j=0; j<<SPAN style="PADDING-BOTTOM: 0px; LINE-HEIGHT: 1.5 !important; MARGIN: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; FONT-FAMILY: 微软雅黑, 宋体; COLOR: rgb(128,0,128); FONT-SIZE: 12px !important; PADDING-TOP: 0px">2; j++)) 4 do 5 read man$i$j 6 done 7 done 8 echo "next print:" 9 for ((i=0; i<<SPAN style="PADDING-BOTTOM: 0px; LINE-HEIGHT: 1.5 !important; MARGIN: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; FONT-FAMILY: 微软雅黑, 宋体; COLOR: rgb(128,0,128); FONT-SIZE: 12px !important; PADDING-TOP: 0px">2; i++))10 do11 for ((j=0; j<<SPAN style="PADDING-BOTTOM: 0px; LINE-HEIGHT: 1.5 !important; MARGIN: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; FONT-FAMILY: 微软雅黑, 宋体; COLOR: rgb(128,0,128); FONT-SIZE: 12px !important; PADDING-TOP: 0px">2; j++))12 do 13 eval echo -n "\$man$i$j:"14 done15 printf "\n"16 done[url=] copycode.jpg [/url]

    5 特殊变量
    $0:当前脚本的文件名
    $num:num为从1开始的数字,$1是第一个参数,$2是第二个参数,${10}是第十个参数
    $#:传入脚本的参数的个数
    $*:所有的位置参数(作为单个字符串)
    $@:所有的位置参数(每个都作为独立的字符串)。
    $?:当前shell进程中,上一个命令的返回值,如果上一个命令成功执行则$?的值为0,否则为其他非零值,常用做if语句条件
    $$:当前shell进程的pid
    $!:后台运行的最后一个进程的pid
    $-:显示shell使用的当前选项
    $_:之前命令的最后一个参数



  • 运维网声明 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-221260-1-1.html 上篇帖子: python twisted 模块安装问题 下篇帖子: Python:完整版 wc 应用技术
    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

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

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

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

    扫描微信二维码查看详情

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


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


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


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



    合作伙伴: 青云cloud

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