变量和引用(2)

Shell变量详解

什么是变量?为什么要使用变量?

各种shell环境中都使用到了“变量”的概念,shell变量用来存放系统和用户需要使用的特定参数(值),而且这些参数可以根据用户的设置或系统环境的变化而相应的变化。通过使用变量,shell程序可以提供更加便捷灵活的功能,实用性和灵活性更强。

常见的shell变量类型包括自定义变量,环境变量,预定义变量,位置变量。

一自定义变量

Bash中的变量操作相对比较简单,不像其他高级编程语言(如C语言,java语言)那么复杂,在定义一个新的变量的时候,一般不需要提前进行声明,而是直接指定变量名称,并赋给初始值即可。

格式:变量名=变量值

变量赋值的特殊操作:

1) 双引号 “”

如图所示,当赋值的内容包含空格时,必须以双引号括起来,其他情况可以省略

2) 单引号 ‘’

当赋值内容包含$,”,\等特殊符号时,应使用单引号括起来,(特殊字符当普通字符对待)。如果赋值内容包含单引号时,需要使用“\’”符号进行转义。

3) 反撇号 ``

主要用于命令替换,允许将执行的某个命令的屏幕输出结果赋值给变量。反撇号括起来的范围内必须能够执行命令行

4) 数值变量的运算

expr 变量1 运算符 变量2 [运算符 变量3]

+ 加法运算

- 减法运算

\*乘法运算

% 求模运算 相除后的余数

二:特殊的shell变量

1) 环境变量

2) 位置变量

位置变量又称位置参数,使用$1 $2$3````表示

例如 Ls –lh /etc ls为执行命令,-lh为第一个位置变量$1,/etc为第二个变量$2

3) 预定义变量

预定义变量是由bash程序预先定义好的一类特殊变量,用户只能使用而不能创建新的预定义变量,也不能直接为预定义变量赋值。常见预定义变量如下:

$# 表示命令行中位置参数的个数

$* 表示所有位置参数的内容

$? 表示前一条命令执行后的返回状态,返回为0表示执行正确,任何非0表示运行出现异常

$0 表示当前执行的脚本或程序名称




1 shell变量基础
shell变量是一种很“弱”的变量,默认情况下,一个变量保存一个串,shell不关心这个串是什么含义。所以若要进行数学运算,必须使用一些命令例如let、declare、expr、双括号等。
shell变量可分为两类:局部变量和环境变量。局部变量只在创建它们的shell中可用。而环境变量则可以在创建它们的shell及其派生出来的任意子进程中使用。有些变量是用户创建的,其他的则是专用shell变量。变量名必须以字母或下划线字符开头。其余的字符可以是字母、数字(0~9)或下划线字符。任何其他的字符都标志着变量名的终止。名字是大小写敏感的。给变量赋值时,等号周围不能有任何空白符。为了给变量赋空值,可以在等号后跟一个换行符。
用set命令可以查看所有的变量,unset var命令可以清除变量var,var相当于没有定义过。readonly var可以把var变为只读变量,定义之后不能对var进行任何更改。
对shell变量的引用方式很多,用这些方式可以方便的获取shell变量的值,变量值的长度,变量的一个字串,变量被部分替换后的值等等。详见表1。
表1 shell变量常见引用方法
2 环境变量
环境变量的定义方法如下:
var=value
export var
shell在初始化的时候会在执行profile等初始化脚本,脚本中定义了一些环境变量,这些变量会在创建子进程时传递给子进程。
用env命令可以查看当前的环境变量。常用的系统环境变量如下:
BASH          展开为调用bash实例时使用的全路径名
CDPATH        cd命令的搜索路径。它是以冒号分隔的目录列表
EDITOR        内置编辑器emacs、gmacs或vi的路径名
ENV           每一个新的bash shell(包括脚本)启动时执行的环境文件。
EUID          展开为在shell启动时被初始化的当前用户的有效ID
GROUPS        当前用户所属的组
HISTFILE      指定保存命令行历史的文件。默认值是~/.bash_history。
HISTSIZE      记录在命令行历史文件中的命令数。默认是500
HOME          主目录。未指定目录时,cd命令将转向该目录
IFS           内部字段分隔符,一般是空格符、制表符和换行符
LANG          用来为没有以LC_开头的变量明确选取的种类确定locale类
OLDPWD        前一个工作目录
PATH          命令搜索路径。一个由冒号分隔的目录列表,shell用它来搜索命令
PPID          父进程的进程ID
PS1           主提示符串,默认值是$
PS2           次提示符串,默认值是>
PS3           与select命令一起使用的选择提示符串,默认值是#?
PS4           当开启追踪时使用的调试提示符串,默认值是 。追踪可以用set –x开启
PWD           当前工作目录。由cd设置
RANDOM        每次引用该变量,就产生一个随机整数。随机数序列可以通过给RANDOM赋值来初始化。
REPLY         当没有给read提供参数时设置
SHELL         当调用shell时,它扫描环境变量以寻找该名字。
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)之类的,表示从倒数第二个元素开始。
下面写个稍微复杂点的例子:

点击(此处)折叠或打开

  1. #!/bin/bash
  2. for ((i=0; i<100; i ))
  3. do
  4. array[$i]=$i
  5. done

  6. for ((i=0; i<100; i ))
  7. do
  8. echo ${array[$i]}
  9. done

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

点击(此处)折叠或打开

  1. for ((i=0; i<2; i ))
  2. do
  3. for ((j=0; j<2; j ))
  4. do
  5. read man$i$j
  6. done
  7. done

  8. echo "next print:"

  9. for ((i=0; i<2; i ))
  10. do
  11. for ((j=0; j<2; j ))
  12. do
  13. eval echo -n "\$man$i$j:"
  14. done

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


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值