Shell 编程2(变量)

变量用于保存有用信息,如路径名、文件名、数字等,Linux用户使用变量定制其工作环境,使系统获知用户相关的配置。变量本质上是存储数据的一个或多个计算机内存地址。

 

变量可分为三类:

本地变量是仅可以在用户当前Shell(就是现在正在使用的这个端口)命期的脚本中使用的变量,类似于C、C++、Java等编程语言中局部变量

环境变量则适用于所有由登录进程所产生的子进程,环境变量在用户登录后到注销之前的所有编辑器、脚本、程序和应用中都有效

位置参数也属于变量,用户用于向Shell脚本传递参数,是只读的


变量替换和赋值


1 变量是某个值的名称,引用变量值就称为变量替换

$符号是变量替换符号,如variable是变量名,那么$variable就表示变量的值

变量赋值有两种格式:

variable=value

${ variable=value }

等号的两边可以有空格,这不影响赋值操作;

如果值(value)中包含空格,则必须用双引号括起来;

变量名只能包括大小写字母(a-zA-Z)、数字(0-9)、下划杠(_)等符号,并且变量名不能以数字开头,否则视为无效变量名

 

eg

variable1=33

variable2=”hello world”

variable3=hello world  这个是错误的  一定要加引号!

 

2 利用unset命令可以清除变量的值,命令格式为:

unset 变量名

eg 

unset variable2

 

3 readonly可将变量设置为只读,变量一旦设置为只读,任何用户不能对此变量进行重新赋值

variable=value                     #先对一个变量进行赋值

readonly variable                 #将variable变量设置为只读

 

eg

color=green

readonly color

color=blur

结果;bash: color: 只读变量


无类型的Shell脚本变量

Shell脚本变量是无类型的,这与awk变量是一样的

bash Shell不支持浮点型,只支持整型和字符型,默认情况下,Shell脚本变量是字符型的,同时,字符型的变量还具有一个整型值,为0;但是,bash Shell并不要求在定义一个变量时声明其类型

Shell会根据上下文判断出数值型的变量,并进行变量的算术运算和比较等数值操作。判断标准是变量中是否只是包含数字,如果变量只包含数字,则Shell认定该变量是数值型的,反之,Shell认定该变量是字符串

eg

脚本:

#!/bin/bash
a=2009
let "a+=1"
echo "a=$a"
b=xx09
echo "b=$b"
declare -i b    将B声明为整数  
echo "b=$b"
let "b+=1"  此处的结果运算过程: 上面强制声明为整数。而字符串的默认整数是0  所以+1后结果为1
echo "b=$b"
exit 0
结果
a=2010
b=xx09
b=xx09
b=1

eg2

脚本

#!/bin/bash
c=""
echo "c=$c"
let "c+=1"
echo "c=$c"
echo "e=$e"
let "e+=1"
echo "e=$e"
exit 0

结果:

c=

c=1

e=

e=1

 

结论:

shell变量有两种类型, 字符,数字(整数!)

字符默认是    “”

数字  默认是  0


有型变量

Shell变量一般是无类型的,但是bash Shell提供了declare和typeset两个命令用于指定变量的类型,两个命令是完全等价的

declare [选项] 变量名

 

-r 将变量设置为只读属性

-i 将变量定义为整型数

-a 将变量定义为数组

-f 显示此脚本前定义过的所有函数名及其内容

-F 仅显示此脚本前定义过的所有函数名

-x 将变量声明为环境变量


eg

#!/bin/bash

var1=2012

var2=$var1+1    什么也没有声明则是字符串

echo "var2=$var2"

 

let "var3=$var1+1"  纯是let的作用

echo "var3=$var3"

 

declare -i var4   声明为整数!

var4=$var1+1

echo "var4=$var4"

 

ming@ming-F83VF:~/shellpractice/chapter9$./vartype.sh

var2=2012+1

var3=2013

var4=2013

 

双小括号方法,即((…))格式,也可以用于算术运算

双小括号方法也可以使bash Shell实现C语言风格的变量操作

 

#!/bin/bash

 

var1=9

var2=10

 

var3=$((var1*var2))  可以直接吧$提到最外面

echo $var3

 

declare命令的-x选项将变量声明为环境变量,相当于export命令,但是,declare -x允许在声明变量为环境变量的同时给变量赋值,export命令不支持此功能

declare -x variable-name=value


环境变量

1 定义环境变量的方法

ENVIRON-VARIABLE=value      #环境变量赋值

export ENVIRON-VARIABLE      #声明环境变量

清除环境变量同样是unset命令


2 env命令可以列出已经定义的环境变量

 

环境变量:对于这个shell以及子shell都可以使用, 一般大写!!!

 

3 PWD和OLDPWD

PWD记录当前的目录路径,当利用cd命令改变当前目录时,系统自动更新PWD的值

OLDPWD记录旧的工作目录,即用户所处的前一个目录

 

4 PATH就记录了一系列的目录列表,Shell为每个输入命令搜索PATH中的目录列表

 

小总结:

对于刚才执行的./null-undeclear.sh  可以在刚才的目录这样执行,但是切换到它的上一级的目录就不能执行,若想执行的话,就要:

./variable/./null-undeclear.sh  其中variablenull-undeclear.sh文件所在的目录

 

ls cat find等这样的命令可以任何的目录中执行,这是为什么?

因为PATH 

linux执行命令的时候会先去PATH中寻找命令所在的目录的

如果想执行的画,就将 null-undeclear.sh目录加入到PATH中!


5  HOME记录当前用户的根目录


6  SHELL变量保存缺省Shell,缺省的值为/bin/bash

 

7 USER和UID是保存用户信息的环境变量,USR表示已登录用户的名字,UID则表示已登录用户的ID

 

8  PPID是创建当前进程的进程号,即当前进程的父进程号

 

9  PS1和PS2 (linux中有PS1  PS2  PS3 PS4)

提示符变量,用于设置提示符格式

PS1是用于设置一级Shell提示符的环境变量,也称为主提示符字符串,即改变: [root @jselab ~]#

eg:

PS1变量是[\u@\h \W]\$,\u、\h、\W和\$表示了特定含义,\u表示当前用户名,\h表示表示主机名,\W表示当前目录名,如果是root用户,\$表示#号,其他用户,\$则表示$号

PS2是用于设置二级Shell提示符的环境变量,

eg 

echo $PS2  结果: >

 

提示符变量中特殊符号及其意义:

模式 意义

\d 以“周 月日”格式显示的日期 日期信息

\H 主机名和域名   host

\h 主机名    host

\s Shell的类型名称    shell

\T 以12小时制显示时间,格式为:HH:MM:SS  time

\t 以24小时制显示时间,格式为:HH:MM:SS   time

\@ 以12小时制显示时间,格式为:am/pm    12小时制显示时间

\u 当前的用户名               user

\v bash Shell的版本号     version

\V bash Shell的版本号和补丁号   

\w 当前工作目录的完整路径     way

\W 当前工作目录名字

\# 当前命令的序列号    #sequence

\$ 如果UID为0,打印#;否则,打印$

 

 

几个重要的配置文件“

 

1

$HOME/.bash_profile是最重要的配置文件,当某Linux用户登录时,Shell会自动执行.bash_profile文件,如.bash_profile文件不存在,则自动执行系统默认的配置文件/etc/profile

 /etc/profile  全局用户 文件   如果修改了此文件中的设置,修改的设置只会影响单个用户

~/.bash_profile 用户个人配置文件, 如果修改了此文件中的设置,只会影响单个用户

/etc/bashrc   全局变量配置文件,此文件中中定义了所有用户的环境变量

~/.bashrc 个人环境变量配置文件,此文件中定义了 用户的环境变量


eg

 cat /etc/profile

结果

# /etc/profile: system-wide .profilefile for the Bourne shell (sh(1))

# and Bourne compatible shells(bash(1), ksh(1), ash(1), ...).

 

if [ "$PS1" ]; then

 if [ "$BASH" ] && [ "$BASH" !="/bin/sh" ]; then

   # The file bash.bashrc already sets the default PS1.

   # PS1='\h:\w\$ '

   if [ -f /etc/bash.bashrc ]; then

     . /etc/bash.bashrc

   fi

 else

   if [ "`id -u`" -eq 0 ]; then

     PS1='# '

   else

     PS1='$ '

   fi

 fi

fi

 

# The default umask is now handledby pam_umask.

# See pam_umask(8) and/etc/login.defs.

 

if [ -d /etc/profile.d ]; then

 for i in /etc/profile.d/*.sh; do

   if [ -r $i ]; then

     . $i

   fi

 done

 unset i

fi

 

exportJAVA_HOME=/usr/lib/jvm/jdk1.7.0_04

 

export JRE_HOME=${JAVA_HOME}/jre

 

exportCLASSPATH=$CLASSPATH:.:$JAVA_HOME/lib:$JAVA_HOME/jre/lib

 

exportCATALINA_HOME=/home/ming/prosoft/tomcat7

 

exportANT_HOME=/home/ming/prosoft/apache-ant-1.8.4

 

exportPATH=$PATH:/home/ming/prosoft/apache-ant-1.8.4/bin

 

如果要使新加入的行立即生效,需要利用source命令执行.bash_profile文。

source命令也称为“点命令”,即句点符号“.”source命令是等价的,source命令通常用于重新执行刚修改的初始化文件,使之立即生效,而不必注销并重新登录

eg

. .bash_profile          #注意:句点符号后面用空格与文件名相分隔

source bash_profile

bash Shell的.bash_login文件来源于C Shell的.login文件,bash Shell的.profile文件来源于Bourne Shell和Korn Shell的.profile文件

当用户登录时,首先查找是否存在.bash_profile文件,若它不存在,则查找是否存在.bash_login文件,若它也不存在,则查找是否存在. profile文件

 

eg:

 脚本:father.sh

#!/bin/bash

echo "Father Process ID is$$"

localvar="Define a localvariable."

echo "localvar=$localvar"

ENVVAR="Define a environmentvariable."

export ENVVAR

echo "ENVVAR=$ENVVAR"

$PWD/child.sh

echo "Return to father process:$$"

echo "localvar=$localvar"

echo "ENVVAR=$ENVVAR"

 

脚本  child.sh

#!/bin/bash

echo "Child Process ID is$$"

echo "My Father Process ID is$PPID"

echo "localvar=$localvar"

echo "ENVVAR=$ENVVAR"

localvar="Redefine this localvariable."

ENVVAR="Redefine thisenvironment variable."

echo "localvar=$localvar"

echo "ENVVAR=$ENVVAR"

 

执行:

./father.sh

结果:

Father Process ID is 5065

localvar=Define a local variable.

ENVVAR=Define a environmentvariable.

Child Process ID is 5066

My Father Process ID is 5065

localvar=

ENVVAR=Define a environmentvariable.

localvar=Redefine this localvariable.

ENVVAR=Redefine this environment variable.

Return to father process: 5065

localvar=Define a local variable.

ENVVAR=Define a environmentvariable.

 

由此可以知道:

子进程对变量的修改不影响父进程,而父进程修改变量会影响子进程!!!!

 

位置参数(positional parameters)是一种特殊的Shell变量,用于从命令行向Shell脚本传递参数

$1表示第1个参数、$2表示第2个参数等等,$0脚本的名字${10}开始,参数号需要用大括号括起来,如${10}${11}${100}……

$*$@一样,表示从$1开始的全部参数

 

$#

命令行或者是位置参数的个数

$*

所有的位置参数,被作为一个单词.

注意:"$*"必须被""引用.

$@

与$* 同义,但是每个参数都是一个独立的""引用字串,这就意味着参数被完整地传递,

并没有被解释和扩展.这也意味着,每个参数列表中的每个参数都被当成一个独立的单词.

注意:"$@"必须被""引用.

 

其他的特殊参数

$-

传递给脚本的falg(使用set 命令).

注意:这起初是 ksh 的特征,后来被引进到Bash 中,但不幸的是,在Bash 中它看上去也不

能可靠的工作.使用它的一个可能的方法就是让这个脚本进行自我测试(查看是否是交

互的).

$!

在后台运行的最后的工作的PID(进程ID).

$_

保存之前执行的命令的最后一个参数.

$?

命令,函数或者脚本本身的退出状态(见Example 23-7)

用于检查上一个命令,函数或者脚本执行是否正确。(在Linux中,命令退出状态为0表示该命令正确执行,任何非0值表示命令出错。)

$$

脚本自身的进程ID.这个变量经常用来构造一个"unique"的临时文件名.

 

这通常比调用mktemp 来得简单.

注意事项:

[1] 当前运行的脚本的PID 为$$.

 

eg

脚本  position.sh

 

#!/bin/sh

echo "The script name is:$0"         

echo "Parameter #1:$1"

echo "Parameter #2:$2"

echo "Parameter #3:$3"

echo "Parameter #4:$4"

echo "Parameter #5:$5"

echo "Parameter #6:$6"

echo "Parameter #7:$7"

echo "Parameter #8:$8"

echo "Parameter #9:$9"

echo "Parameter#10:${10}"        

 

echo"-------------------------"

echo "All the command lineparameters are: $*"

 

运行:

./position.sh a b c d e f g h I j

结果:

The script name is: ./position.sh

Parameter #1:a

Parameter #2:b

Parameter #3:c

Parameter #4:d

Parameter #5:e

Parameter #6:f

Parameter #7:g

Parameter #8:h

Parameter #9:i

Parameter #10:j

-------------------------

All the command line parameters are:a b c d e f g h i j

 

引用:

引用指将字符串用引用符号括起来,以防止特殊字符被Shell脚本重解释为其他意义,特殊字符是指除了字面意思之外还可以解释为其他意思的字符

eg

ls i*

列出以i开头的文件

ls “i*”

则列出 i*  这个文件

 

双引号引用除美圆符号($)、反引号(`)和反斜线(\)之外的所有字符,即$、`和\在双引号中仍被解释为特殊意义

eg

脚本:

#!/bin/bash

variable1=2010

echo "$variable1"

echo $variable1

 

variable2="X    Y   Z"

echo "$variable2"

echo $variable2

 

执行结果:

2010

2010

X   Y   Z (由于要保留原有的空格,则必须使用””引号)

X Y Z (若不使用,则将空格给变成单个)

 

在双引号中保持$符号的特殊意义可以引用变量,如“$variable”表示以变量值替换变量名

用双引号引用变量能够防止字符串分割,保留变量中的空格

 

单引号引用了所有字符,即单引号中字符除单引号本身之外都解释为字面意义,单引号不再具备引用变量的功能

通常将单引号的引用方式称为全引用将双引号的引用方式称为部分引用

 

eg

echo “$PWD”

/home/ming/shellpractice/variable

 

echo ‘#PWD’

$PWD

 

命令替换的两种格式:  命令替换 反引号:`

第一种  `Linux 命令`

第二种   $( Linux 命令)

 

eg

echo `whoo`

No command 'whoo' found, did youmean:

它将反引号中的内容  当作命令执行!!


eg

echo `who`

ming pts/2 2012-11-21 09:40 (:0.0)ming pts/3 2012-11-21 10:37 (:0.0)

 

eg

currentTime=`date`

echo $currentTime

2012年 11月 21日 星期三 10:38:53 CST

 

这个反引号的作用在  它可以和cjava c++等高级语言程序结合起来一起使用

 

一个c的程序

main.c

 

#include <stdio.h>

 

main ()

{

 printf ("This is the output from Cprogram.");

}

 

 

ming@ming-F83VF:~/shellpractice/variable$gcc -o main main.c

ming@ming-F83VF:~/shellpractice/variable$printdata=`./main`

ming@ming-F83VF:~/shellpractice/variable$echo $printdata

This is the outputfrom C program.

(生城了main可执行文件)

 

 

转义:

 

反斜线符号(\)表示转义,当反斜线后面的一个字符具有特殊意义时,反斜线将屏蔽下一个字符的特殊意义,而已字面意义解析它

 

shell 中的数组

数组的格式: 

ARRAY[Iindex]


定义数据

(1)第一种方式   array={1 2 3 4 5}

(2)第二中方式   array[0] =1;array[0 =2


数组的使用

(1) echo ${arr[1]}    显示某个元素

(2)echo $arr 默认引用数组的第一个元素

(3)echo ${arr[@]:2}  查看数组中  下标大于等于2的所有元素

(4)echo ${#arr[@]} 数组元素中的个数


清除数组

unset arr[0]  清除数组中 第1个元素

unset arr 清除真个数组


间接变量引用

如果第一个变量的值是第二个变量的名字,从第一个变量引用第二个变量的值就称为间接变量引用

variable1=variable2

variable2=value

variable1的值是variable2,而variable2又是变量名,variable2的值为value,间接变量引用是指通过variable1获得变量值value的行为

 

bash Shell提供了两种格式实现间接变量引用

eval tempvar=\$$variable1

tempvar=${!variable1}

 

eg

#!/bin/bash

 

var1=var2

var2=hadoop

echo "var1=$var1"

 

eval tempvar=\$$var1

echo"tempvar=$tempvar"

echo "var1=${!var1}"

 

结果

var1=var2

tempvar=hadoop

var1=hadoop

 

eg

#!/bin/bash

stu1_name=anders

stu1_address=shanghai

 

stu2_name=james

stu2_address=beijing

 

PS3="Pls : Enter Number->"

select number in 12

do

    stu_name=stu${number}_name     此处的值变为:stu1_name或者为 stu2_address

    stu_address=stu${number}_address

 

    echo"name : ${!stu_name}"

    echo"address : ${!stu_address}"

break

done

 

运行:

ming@ming-F83VF:~/shellpractice/chapter9$./test2.sh

1) 1

2) 2

Pls : Enter Number-> 1

name : anders

address : shanghai



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值