Shell特殊变量和命令行参数详解

1.shell变量基础

shell变量是一种很“弱”的变量,默认情况下,一个变量保存一个串,shell不关心这个串是什么含义。

所以若要进行数学运算,必须使用一些命令例如let、declare、expr、双括号等。

shell变量可分为两类:局部变量和环境变量。

局部变量只在创建它们的shell中可用;而环境变量则可以在创建它们的shell及其派生出来的任意子进程中使用。

有些变量是用户创建的,其他的则是专用shell变量。

变量名必须以字母或下划线字符开头。其余的字符可以是字母、数字(0~9)或下划线字符。

任何其他的字符都标志着变量名的终止。

名字是大小写敏感的。

给变量赋值时,等号周围不能有任何空白符。

为了给变量赋空值,可以在等号后跟一个换行符。

用set命令可以查看所有的变量,unset var命令可以清除变量var,var相当于没有定义过。readonly var可以把var变为只读变量,定义之后不能对var进行任何更改。

对shell变量的引用方式很多,用这些方式可以方便的获取shell变量的值,变量值的长度,变量的一个字串,变量被部分替换后的值等等。

shell变量常见引用方式如下:

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)之类的,表示从倒数第二个元素开始。 下面写个稍微复杂点的例子:

如果要使用二维数组甚至三维数组该怎么实现呢,那就需要用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实现二维数组了。 下面实现的二维数组每一行代表一个人的信息记录,包括姓名,年龄。

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

本文分享自微信公众号 - 马哥Linux运维(magedu-Linux)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2017-03-07

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏技术博文

php面试题整理

1.禁用COOKIE 后 SEESION 还能用吗? 答:通常服务器端的session是借助于seesion cookie来和客户端交互的。 但如果客户端禁用了...

43880
来自专栏Golang语言社区

Golang语言捕获panic异常并转化为error

package mainimport ( "fmt" "errors")func testPanic2Error() (err erro...

42450
来自专栏技术记录

Protobuf3语法详解

1.5K50
来自专栏Jimoer

Java程序优化之替换swtich

关键字switch语句用于多条件判断,功能类似于if-else语句,两者性能也差不多,不能说switch会降低系统性能。在绝大部门情况下,switch语句还是有...

308110
来自专栏前端达人

JavaScript基础——深入学习async/await

大家好,上周我们一起学习了《JavaScript基础——Promise使用指南》, 明白了ES6增加的新特性——Promise让我们能够更加优雅的书写回调函数,...

386170
来自专栏软件开发 -- 分享 互助 成长

谈谈 char *num="123";和char num[4]="123";的区别

最近写程序的时候发现这样一个问题 #include<iostream> #include <string.h> using namespace std; vo...

23280
来自专栏desperate633

设计模式之桥接模式(Bridge 模式)类的功能层次类的实现层次类的层次结构的混杂与分离桥接模式的具体实例小结

Bridge的意思是桥梁,作用就是将两边连接起来。桥接模式的作用也是如此,桥接模式分别类的功能层次和类的实现层次连接起来。

8610
来自专栏章鱼的慢慢技术路

Go指南练习_Stringer

14720
来自专栏desperate633

设计模式之代理模式(Proxy模式)代理模式的引入代理模式的实例程序代理模式分析

Proxy是代理人的意思,指的是代替别人进行工作的人。当不一定需要本人亲自去做的工作的时候,就可以寻找代理人去完成。 但在代理模式中,往往是相反的,通常是代理...

10420
来自专栏北京马哥教育

一篇文章学会shell工具篇之sed

? sed工具执行原理; 有关sed的参数及action的常见操作方法; 定址; 模式空间和保持空间; 使用标签 1.首先先来了解一下什么是sed? sed叫...

33670

扫码关注云+社区

领取腾讯云代金券