shell变量详解

来源:互联网 发布:nginx listen 编辑:程序博客网 时间:2024/06/06 17:58

        Bash是Linux distribution 的标准shell,Linux是多用户多任务的环境,每个用户登录都会取得一个bash,

每个用户可以使用bash执行相关的命令,例如执行mail这个命令来获取自己的邮件,这时bash就可以通过"变量”

来得知你的邮箱是哪个文件了。再比如你写了一个很长的shell脚本,脚本中多次出现了某一个命令或是路径,

如果觉得路径不对想修改一下,就得一个个修改或是使用批量替换的命令,这样做很麻烦,脚本也显得臃肿了很多,

变量的作用就可以解决这个问题。

在shell中有环境变量 用户自定义变量和系统预设变量。

1.系统默认环境变量(大写字符)

当shell程序启动时,都自动设置一组变量,这组变量就是环境变量。shell中的所有命令都可以使用这些参数。

env命令可以查看系统预设的全部环境变量,登录不同用户,环境变量的值也不同。

列举几个常见的环境变量:

HOSTNAME=localhost.localdomain            主机名

SHELL=/bin/bash                                        当前用户的shell类型

HISTSIZE=1000                                           历史记录数,默认1000

PATH=/usr/lib/qt-3.3/bin:/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin:/home/yang/bin

                                                                     执行文件查找的路径,冒号为分隔符

HOME=/root                                                 代表当前用户的主目录,是cd命令的默认参数

MAIL=/var/spool/mail/yang                          当前用户文件存放目录

LANG=zh_CN.UTF-8                                  与语系有关的环境变量,多语言环境可以修改此变量

PWD=/root                                                  当前工作目录。由cd设置

TERM=xterm                            终端机使用的环境类型

2.用户自定义变量

定义变量的格式为:变量名=变量的值,等号两边不能有空格符,变量名只能是英文字母数字和下划线组成,但是不能以数字开头。

在脚本中引用变量必须在变量前加上变量替换操作符“$"。

[root@localhost ~]# myname=seven     #变量声明(赋值)。
[root@localhost ~]# echo $myname
seven

取消设置的变量使用unset

[root@localhost ~]# unset myname
[root@localhost ~]# echo $myname

[root@localhost ~]#

注意(1)若变量内容里带有特殊字符(如空格),需要加上单引号或双引号

                [root@localhost ~]# name="seven's name"        (含有空格和单引号)
                [root@localhost ~]# echo $name         
                seven's name

                       

                       [root@seven ~]$myname="seven's    name"

                   [root@seven ~]$ echo $myname      #替换变量就不会保留空白

                   seven's name

                   [root@seven ~]$ echo "$myname"   #引用一个变量保留其中的空白

                   seven's    name

                [root@localhost ~]# echo 'hello,world!'
                hello,world!

              [root@localhost ~]# echo "hello, world!"  
               -bash: !": event not found                         注:若要打印!,就不要将其放入双引号中,可以加上转义字符(5)

          (2)变量内容中本身带有单引号,刚需要加双引号(同1)

           (3)双引号中的特殊字符$可以保持原本特性。(部分引用:发生变量替换)

               [root@localhost ~]# var="lang is $LANG"
               [root@localhost ~]# echo $var
               lang is zh_CN.UTF-8

           (4)单引号内的特殊字符则仅为一般字符(纯文本),里面的特殊字符全部失去本身的作用(全引用:不会发生变量替换)

              [root@localhost ~]# var1='lang is $LANG'
              [root@localhost ~]# echo $var1
              lang is $LANG

             [root@localhost ~]# echo '$var1'

              $var1

           (5)可以用转义字符"\"将特殊字符(Enter,$,\,空格符,!等)变成一般字符。

             [root@localhost ~]# name=seven\'s\ name 

             [root@localhost ~]# echo $name 

             seven's name


     (6)如果变量内容中需要用到其他命令的运行结果,可使用反引号`命令`或是$(命令)

      反引号是键盘上方数字键1左边的那个按键。

      [root@localhost ~]# route=`pwd`
      [root@localhost ~]# echo $route
      /root

      [root@localhost ~]# version=$(uname -r) 
      [root@localhost ~]# echo $version      
      2.6.32-358.el6.i686

      (7)若变量为了增加变量内容时,可用 "$变量" 或 ${变量}累加内容

      [root@localhost ~]# name="$name"all    
      [root@localhost ~]# echo $name     
      seven's nameall

      [root@localhost ~]# name=${name}all
      [root@localhost ~]# echo $name     
      seven's nameallall

     (8)获得字符串的长度

     [root@localhost ~]# var=1234567890098765
      [root@localhost ~]# echo ${#var}
      16

自定义变量有一个好处就是可以定义一个变量来代替一个很长的经常使用的工作目录,即使以后将其他目录

作为工作目录,只要更改这个变量即可。

   用于终端打印的另一个命令是printf,prinft并不像echo命令一样会自动添加换行符。

[root@localhost ~]# printf "%-5s %-10s %-6s\n" NO name score

                    printf "%-5s %-10s %-6.2f\n" 1 tony 77.567  
NO    name       score 

1     tony       77.57 

-5s指明了一个格式为左对齐且宽度为5的字符串替换,如果不用-对齐方式字符串就采用右对齐形式。.2指定保留2个小数位。


 env命令只可查看环境变量,使用set命令则可查看所有变量,包括环境变量,用户自定义变量,还有一些与bash接口有关的变量。

(1)命令提示符 PS1='[\u@\h \W]\$ '当我们每次按下[Enter]键去执行某个命令后,最后要再次出现提示符时,就会主动去读取这个变量。

\u代表目前用户的账户名称,\h 仅取主机名第一个小数点之前的名字,\W利用basename函数取得工作目录名称(~表示当前目录),\$提示符,root是#,其他是$.

[root@localhost ~]# PS1='[\u@\h \W \A]\$'      \A显示时间 24小时格式的 HH:MM

[root@localhost ~ 16:59]#

(2)$ shell的PID ,$本身也是一个变量,代表这个Shell的线程代号。echo $$可查看。

3? 这个变量代表上个命令的回传码。当我们执行某个命令时,这些命令都会回传一个执行后的代码,如果成功执行该命令,则会回传一个0值。

     如果执行过程发生错误,则回传错误代码(非0)


3.自定义变量变成环境变量

    当登录Linux并取得一个bash后,这就是一个独立的进程(父进程)。当用bash命令再打开一个shell,则操作的环境接口会进入子进程中,

此时先前设置的变量name,PS1='[\u@\h \W \A]\$' 都不存在了,exit命令退出当前的shell回到原来的shell,变量都还在。

子进程只会继承父进程的环境变量,不会继承父进程的自定义变量,所以环境变量和自定义变量的差异在于会不会被子进程所继续引用。

想让设置的变量一直生效(即使用户退出再登录) 1.允许系统内所有用户登录后都能使用该变量。

    [root@localhost ~]# echo "export myname=seven" >>/etc/profile
    [root@localhost ~]# source /etc/profile
    [root@localhost ~]# bash
    [root@localhost ~]# echo $myname
    seven

    [root@localhost ~]# su - wuqi
    [wuqi@localhost ~]$ echo $myname
    seven

注:/etc/profile是每个用户登陆取得bash时一定会读取的配置文件,如果想要帮所有用户设置整体环境,修改这个文件,不过谨慎使用。

    2.仅允许当前用户使用该变量  

    [root@localhost ~]# echo "export myname=seven" >> ~/.bashrc             当前用户主目录下的.bashrc个人配置文件,当登陆或打开新的shell时,该文件被读取。 ~/表示当前用户主目录
    [root@localhost ~]# source ~/.bashrc

    此时再登陆另一个账号,myname变量不再生效了。

4.shell script 默认变量($1,$2...)

   执行shell script脚本文件时后面可以带有位置参数

 sh scriptname.sh  opt1 opt2 opt3 .....

       $0      $1   $2   $3  .....

$0当前脚本的文件名

$n:n为从1开始的数字,$1是第一个参数,$2是第二个参数,.......

还有一些特殊的变量可以在script内使用来调用这些参数。

$#:后接参数的个数

$@:列出参数"$1","$2","$3",每个参数是独立的,用双引号括起来

$*:"$1c$2c$3",c为分隔符,默认的是空格,以单个字符串列出所有的参数。

$!后台运行的最后一个进程的pid

注:当n>10时获取第n个参数的值时,必须使用${n}来获取。


5.变量的读取和声明:read ,declare以及数值计算

  (1)read [-pt] varible

  -p:后面可以接提示符

  -t: 后面可接等待的秒数。

[root@localhost ~ 22:27]$read -p "please input your name: " -t 30 name
please input your name:

“$变量”有两种取得方式:1.直接执行的方式:script.sh variable,这也是Linux服务启动放置目录/etc/init.d下 大多数程序的设计方式

                         2.交互式:通过read命令让用户输入变量的内容。 


(2)shell中默认把变量值当作字符串

[root@localhost ~10:13]#a=1
[root@localhost ~10:13]#b=$a+1
[root@localhost ~10:13]#echo $b
1+1

结果不是 2,因为shell将其解释为字符串,而不是数学运算。

可利用declare把变量定义为整型,此后每次运算,都把a的右值识别为算术表达式或数字

[root@localhost ~10:17]#declare -i a=1
[root@localhost ~10:17]#a=$a+1

[root@localhost ~10:18]#echo $a
2

对于数值计算可以采用这种方式进行运算:var=$((运算内容)),也可使用[]操作符

[root@localhost ~10:51]#b=$(($b+1))
[root@localhost ~10:51]#echo $b
2

let命令也可以执行基本的算术操作

#!/bin/bash

s1=4

s2=3

let result=s1+s2

echo $result

let s1--

let s2+=2

(3)如果需要非字符串类型的变量,那就要进行变量的声明才行

declare 声明变量的类型

-a 数组  -i 整型 -x 环境变量 -r readonly类型,该变量不可更改也不能重设。"-"变成"+"可以取消变量

但declare只能暂时声明变量,当退出再登录时变量不存在了。

可使用export命令查看所有声明的变量



0 0