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给用户
MAILCHECKshell检查MAIL文件的周期,单位是秒
MAILPATH功能与MAIL类似,但可以用一组文件,以冒号分隔,每个文件后可跟一个问号和一条发向用户的消息
SHELLshell的路径名
TERM终端类型
TMOUTshell自动退出的时间,单位为秒,若设为0则禁止shell自动退出
PROMPT_COMMAND指定在主命令提示符前应执行的命令
PS1主命令提示符
PS2二级命令提示符,命令执行过程中要求输入数据时用
PS3selcet的命令提示符
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非空串时为真。


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

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值