shell变量

在shell中有3种变量:系统变量,环境变量和用户变量,其中系统变量在对参数判断和命令返回值判断时会使用,环境变量主要是在程序运行时需要

设置,用户变量在编程过程中使用量最多。

1。系统变量

常用的系统变量
变量名       含义
$#

    命令行参数的个数

$n

   $1表示第一个参数,$2表示第二个参数,以此类推

$0
当前程序的名称
$?

前一个命令或许或函数的返回码

$*

以“参数1 参数2 。。。”形式保存所有参数

$@

以“参数1”“参数2”。。。形式保存所有参数

$$ 本程序的(进程ID号)PID
$! 上一个命令的PID


 

例如下面是sysvar.sh的脚本内容。

#!/bin/sh

#This script explains how the system variable works

 

echo "The name of the program is $0"

echo " You''ve input $# parameters.They are $*"

echo " And the first one of them is $1"

echo " The PID of this program is $$"

echo "... "

echo " You've executed correctly,and the return code is $?"

其输出如下:

The name of the program issysvar.sh【$0表示当前程序名】

You''ve input 2 parameters.They arehello world【$*表示所有的参数】

 And the first one of them ishello【$1表示第一个参数】

The PID of this program is1504【$$本程序的PID】

...

You've executed correctly,and the return code is0【$?表示返回码,如果为零则表示真】

2。环境变量

当shell程序启动时,都自动设置一组变量,这组变量就是环境变量。shell中的所有命令都可以使用这些参数,例如之前博客中提到的LOGNAME变量。环境变量可以在~/.bash_profile或者~/.bashrc中设置,

下面列举了常见的环境变量:

常见的环境变量
变量名 含义

PATH

命令搜索路径,以冒号为分隔符。注意与DOS下不同的是当前目录不在系统路径里
HOME 用户home目录的路径名,是cd命令的默认参数
COLUMNS 定义了命令编辑模式下可使用命令行的长度
EDITOR 默认的行编辑器
VISUAL 默认的可视编辑器
FCEDIT 命令fc使用的编辑器
HISTFILE 命令历史文件
HISTSIZE 命令历史文件中最多可包含的命令条数(默认1000条)
HISTFILESIZE 命令历史文件中包含的最大行数
IFS 定义shell使用的分隔符
LOGNAME 用户登录名
MAIL 指向一个需要shell监视其修改时间的文件。当该文件修改后,shell将发消息You have mail给用户
MAILCHECK shell检查MAIL文件的周期,单位是秒
MAILPATH 功能与MAIL类似,但可以用一组文件,以冒号分隔,每个文件后可跟一个问号和一条发向用户的消息
SHELL shell的路径名
TERM 终端类型
TMOUT shell自动退出的时间,单位为秒,若设为0则禁止shell自动退出
PROMPT_COMMAND 指定在主命令提示符前应执行的命令
PS1 主命令提示符
PS2 二级命令提示符,命令执行过程中要求输入数据时用
PS3 selcet的命令提示符
PS4 调试命令提示符
MANPATH 寻找手册页的路径,以冒号分隔
LD_LIBRARY_PATH 寻找库的路径,以冒号分隔


 

当然也可以定义新的环境变量,使用export命令即可。

#export NEW_ENV_VAR="This is a new environment variable"

#echo "$NEW_ENV_VAR"

This is a new environment variable

 

ps:

RANDOM
这个玩意儿就是『随机随机数』的变量啦!目前大多数的 distributions 都会有随机数生成器,那就是 /dev/random这个文件。 我们可以透过这个随机数文件相关的变量 ($RANDOM) 来随机取得随机数值喔。在 BASH 的环境下,这个 RANDOM 变量的内容,介于 0~32767 之间,所以,你只要 echo $RANDOM 时,系统就会主动的随机取出一个介于 0~32767 的数值万一我想要使用 0~9 之间的数值呢?呵呵~利用 declare 宣告数值类型, 然后这样做就可以了:

[root@SOR_SYS ~]#  echo $RANDOM
14522

[root@SOR_SYS ~]# declare -i number=$RANDOM*10/32768 ; echo $number
6

 

假如说想修改HISTSIZE的默认记录命令个数,就可以在命令行下执行

[root@SOR_SYS ~]# sed -i 's/HISTSIZE=1000/HISTSIZE=10000/g' /etc/profile
[root@SOR_SYS ~]# source /etc/profile

或者直接在文件中修改就ok!

3.用户变量

用户变量最长用到的变量,使用也十分简单。用户定义的变量名必须由字母数字下划线组成,并且变量名的第一个字符不能为数字。

//以下都是不合法的变量

abc#123 //变量名中不能包含除字母数字及下划线以外的字符

123aBc //第一个字符不能为数字

4。变量的赋值和使用

shell 下的变量和C中的变量不同,无需声明即可使用,赋值同时即声明了变量。对于用户变量,用户可按如下方法赋值。

variable_name=value

eg:season=Winter

【赋值时,变量和等号之间不要有空格,等号和值之间也不要有空格,否则shell不会认为变量被定义。】

同时,shell也允许在变量间进行相互赋值。引用变量时,需要在变量名前面加$符号。

eg:current_season=$season

使用变量时,需要在变量名钱加$符号,例如echo $season。当然使用时也会遇到一些比较特殊的情况,就是变量名包含在其他字符串中,这时就需要用{}将变量名括起来。

#a=good

#echo “${a}morning”【为了避免变量名上造成混淆,建议总是使用{}将变量名括起来】

输出结果为:goodmorning

若要重置某一变量,即可使用unset命令清空某一变量的赋值

eg:

#a=good

#echo “{a}morning”

goodmorning

#unset a

#echo “{a}morning”

morning

另外,如果在赋值后不希望改变变量,使其类似于常数,则可以使用readonly命令将其设为只读

//先赋值,再设置只读

#a=good

#readonly a

//或者直接在赋值时设置只读

#readonly good

此时若用unset命令重置变量a或者对a重新赋值,则会产生错误。

#unset a

-bash: a: readonly variable

#a=Good

-bash: a: readonly variable

另外,shell的变量默认是全局作用的,如果需要在一定范围内生效,则需要加上local限制。例如local a将设置a为局部变量

当然也可以对数组进行赋值,对于已有的数组,也可以对其中一个元素赋值,方法如下:

//直接从index为0顺序赋值

ARRAY=(value1 value2 。。。valueN)

//同时指定index和value

ARRAY=(index1=value1 index2=value2 。。。indexN=valueN)

//为单一元素赋值

ARRAY[INDEX]=value  【数组的index从0开始】

使用数组的方法为${ARRAY[index]},示例如下:

#!/bin/bash

#定义arr数组

arr=(a b c)

#对其中一个元素赋值

arr[3]=d

 

echo ${arr[0]}

echo ${arr[3]}

bash中的数组变量:
a[0]=1
a[1]=2
a[2]=3
等价于a=(1,2,3)
注意:等号两边不能有空格
echo ${a[0]}正确输出
echo $a[0]错误输出
echo ${a[*]}和echo ${a[@]}输出数组a中所有的项目


5。数字和数组的声明

默认的赋值是对字符串赋值,例如执行如下脚本,就会发现这个脚本并没有使用5和6相加输出“11”,而是输出“5+6”。

#!/bin/bash

a=5

b=6

c=$a+$b

echo $c

如果要对数字或数组进行声明,则要declare命令,例如上例改成如下形式,即可正常进行加减。

#!/bin/bash

declare -i a=5

declare -i b=6

declare -i c=$a+$b

echo $c

declare支持的声明类型如下。使用“- 类型”开启,“+ 类型”关闭

(1)i:定义整数integer

(2)a:定义数组array

(3)f:定义函数function

(4)r:定义为只读readonly

(5)x:定义为通过环境输出变量

例如对声明数组变量的方法如下。

#!/bin/bash

declare -a arr=(a b c )

 

另外:

echo $(( 13 % 3 )) 

至於数值运算上的处理,则有:『+, -, *, /, % 』等等。 那个 % 是取余数啦

6.运算类(其中包括字符和数值)

-n表示non-zero非空串时为真。

shell变量_第1张图片

shell变量_第2张图片


ref: http://blog.csdn.net/zhuying_linux/article/details/6633022



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

复制代码
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使用的当前选项
$_:之前命令的最后一个参数


ref: http://www.cnblogs.com/barrychiao/archive/2012/10/22/2733210.html

你可能感兴趣的:(shell变量)