Bash中的变量

变量是脚本编程中进行数据表现的一种方法。说白了,变量不过是计算机为了保留数据项,而在内存中分配的一个位置或一组位置的标识或名字。变量既可以出现在算术操作中,也可以出现在字符串分析过程中。

变量赋值

变量使用=来实现赋值操作,前后都不能有空白。例如:

a=314
echo "The value of \"a\" is $a."

也可以使用let来赋值:

let a=16+5
echo "The value of \"a\" is now $a."

使用read命令进行赋值:

echo -n "Enter \"a\" "
read a
echo "The value of \"a\" is now $a."

下面是复杂一点的赋值:

a=23
echo $a
b=$a
echo $b

我们也可以使用命令替换来赋值:

a=`echo Hello!`   # 把'echo'命令的结果传给变量'a'
echo $a

a=`ls -l`         # 把'ls -l'的结果赋值给'a'
echo $a        # 然而, 如果没有引号的话将会删除ls结果中多余的tab和换行符.
echo "$a"      # 如果加上引号的话, 那么就会保留ls结果中的空白符.

注意: 上面的代码有无引号,在linux系统中,运行结果是不一样的;在mac系统上,结果是一致的。

也可以使用$(...)机制来进行变量赋值,这其实还是命令替换的一种形式。例如:

# From /etc/rc.d/rc.local
R=$(cat /etc/redhat-release)
arch=$(uname -m)

变量的类型

不像其他程序语言一样,Bash并不对变量区分”类型”。本质上,Bash变量都是字符串。但是依赖于具体的上下文,Bash也允许比较操作和整数操作。其中的关键因素就是,变量中的值是否只有数字。

整型的变量:

a=2334                   # 整型.
let "a += 1"
echo "a = $a "        # a = 2335

把变量编程字符串:

b=${a/23/BB}     # 将"23"替换成"BB"
echo "b = $b"     # b = BB35

对字符串类型变量计算加法:

let "b += 1"             # BB35 + 1 =
echo "b = $b"        # b = 1

将上面过程反过来操作:

c=BB34
echo "c = $c"               # c = BB34
d=${c/BB/23}               # 将"BB"替换成"23".

# 这使得变量$d变为一个整形.
echo "d = $d"               # d = 2334
let "d += 1"                # 2334 + 1 =
echo "d = $d"               # d = 2335

null变量可以用在算术操作中,下面例子将null变量转换成一个整型变量:

e=""
echo "e = $e"            # e =
let "e += 1"            # 算术操作允许一个null变量?
echo "e = $e"            # e = 1

对于没有声明的变量,也可以转换成一个整型变量:

echo "f = $f"               # f =
let "f += 1"                # 算术操作能通过么?
echo "f = $f"               # f = 1

不区分变量的类型既是幸运的事情也是悲惨的事情。它允许你在编写脚本的时候更加的灵活(但是也足够把你搞晕!),并且可以让你能够更容易的编写代码。然而,这也很容易产生错误,并且让你养成糟糕的编程习惯。

另外,变量还分局部变量和环境变量。局部变量只在代码块或者函数中可见;环境变量将影响用户接口和shell行为。

在通常情况下,每个进程都有自己的”环境”,这个环境是由一组变量组成的,这些变量中存有进程可能需要引用的信息。在这种情况下,shell与一个一般的进程没什么区别。

但是,分配给环境变量的空间是有限的。创建太多环境变量,或者给一个环境变量分配太多的空间都会引起错误。

如果一个脚本要设置一个环境变量,那么需要将这些变量export出来,也就是需要通知到脚本本地的环境。但是,子进程是不能够export变量来影响产生自己的父进程的环境的。

位置参数

变量是有位置参数的,从命令行传递到脚本的参数: $0, $1, $2, $3 . . .

$0就是脚本文件自身的名字,$1是第一个参数,$2是第二个参数,$3是第三个参数,然后是第四个。$9之后的位置参数就必须用大括号括起来了,比如:${10}, ${11}, ${12}

两个比较特殊的变量$*$@表示所有的位置参数。

{}标记法提供了一种提取从命令行传递到脚本的最后一个位置参数的简单办法,但是这种方法同时还需要使用间接引用

args=$#           # 位置参数的个数.
lastarg=${!args}
# 或:  lastarg=${!#}
# 注意,不能直接使用 lastarg=${!$#} ,这会产生错误

如果脚本需要一个命令行参数,而在调用的时候,这个参数没被提供,那么这就可能造成给这个参数赋一个null变量,通常情况下,这都会产生问题。一种解决这个问题的办法就是使用添加额外字符的方法,在使用这个位置参数的变量和位置参数本身的后边全部添加同样的额外字符。

variable1_=$1_  # 而不是 variable1=$1
# 这将阻止报错, 即使在调用时没提供这个位置参数

critical_argument01=$variable1_

#使用正则表达式替换_为空,得到输入的变量
variable1=${variable1_/_/}

另外,一种方法是判断是否存在:

if [ -z $1 ]
then
    exit $E_MISSING_POS_PARAM
fi

更好的方法是使用参数替换:

DefaultVal=xxxx
${1:-$DefaultVal}

shift命令会重新分配位置参数,其实就是把所有的位置参数都向左移动一个位置。这样的话,原来的$1就消失了,但是$0(脚本名)是不会改变的。如果传递了大量的位置参数到脚本中,那么shift命令允许你访问的位置参数的数量超过10个,当然{}标记法也提供了这样的功能。

下面是使用shift命令的例子:

#!/bin/bash
# 使用'shift'来逐步存取所有的位置参数. 

#  给脚本命个名,比如shft,然后给脚本传递一些位置参数, 比如:
#          ./shft a b c def 23 skidoo

until [ -z "$1" ]  # 直到所有的位置参数都被存取完...
do
    echo -n "$1 "
    shift
done

echo                # 额外的换行.

exit 0

当然,shift命令也可以用在函数当中。

multiply ()                     # 将乘数作为参数传递进来.
{                                     # 可以接受多个参数. 

local product=1

until [ -z "$1" ]               # 直到处理完所有的参数...
do
    let "product *= $1"
    shift
done

echo $product               #  不会echo到stdout
}

变量替换

变量的名字就是变量保存值的地方,引用变量的值就叫做变量替换。

如果variable1是一个变量的名字,那么$variable1就是引用这变量的值,即这边变量所包含的数据。

没有$前缀的时候,变量可能存在如下几种情况:

  • 变量被声明或被赋值
  • 变量被unset
  • 变量被export
  • 变量代表一种信号

变量赋值可以使用=,也可以在read命令中或者循环头进行赋值,例如for var2 in 1 2 3

注意,$variable事实上只是${variable}的简写形式。在某些上下文中$variable可能会引起错误,这时候你就需要用${variable}了。

被一对双引号括起来的变量替换是不会被禁止的,所以双引号被称为部分引用,有时候又被称为”弱引用”。但是,如果使用单引号的话,那么变量替换就会被禁止了,变量名只会被解释成字面的意思,不会发生变量替换,所以单引号被称为全引用,有时候也被称为”强引用”。

变量赋值和替换,举例如下:

a=375
hello=$a

echo hello    # 没有变量引用,只是个hello字符串

echo $hello         # 375
echo ${hello}      # 375

echo "$hello"       # 375
echo "${hello}"     # 375

# 全引用的作用将会导致"$"被解释为单独的字符,而不是变量前缀
echo '$hello'          # $hello

引用一个变量将保留其中的空白,但如果是变量替换,就不会保留了

hello="A B  C   D"
echo $hello                  # A B C D
echo "$hello"               # A B  C   D

一个未初始化的变量是没有值的,但是在做算术操作的时候,这个未初始化的变量看起来值为0。这是一个未文档化(并且可能不具可移植性)的行为。

echo "$uninitialized"                # (blank line)
let "uninitialized += 5"                # Add 5 to it.
echo "$uninitialized"                # 5

变量引用

在一个双引号中通过直接使用变量名的方法来引用变量,一般情况下都是没问题的。这么做将阻止所有在引号中的特殊字符被重新解释,包括变量名,但是$、`(后置引用)、和\除外。保留$作为特殊字符的意义是为了能够在双引号中也能够正常的引用变量,也就是说,这个变量将被它的值所取代。

使用双引号还能够阻止单词分割,如果一个参数被双引号扩起来的话,那么这个参数将认为是一个单元,即使这个参数包含有空白,那里面的单词也不会被分隔开。

hello="A B  C   D"
echo $hello                  # A B C D
echo "$hello"               # A B  C   D

在echo语句中,只有在单词分割或者需要保留空白的时候,才需要把参数用双引号括起来。

谈到空白,我们可以通过IFS变量修改默认的空白符,例如:

var="'(]\\{}\$\""

# 下面输出一样
echo $var        # '(]\{}$"
echo "$var"      # '(]\{}$"

IFS='\'
# 下面输出不一样了,因为这里空白字符定义为\了,变量替换的时候,会将其替换为一个空格
echo $var        # '(] {}$"
echo "$var"      # '(]\{}$"

单引号操作与双引号基本一样,但是不允许引用变量,因为$的特殊意义被关闭了。在单引号中,任何特殊字符都按照字面的意思进行解释,除了’,所以说单引号是一种比双引号更严格的引用方法。

因为即使是转义符在单引号中也是按照字面意思解释的,所以如果想在一对单引号中显示一个单引号是不行的。对于下面的例子:

echo "Why can't I write 's between single quotes"

使用单引号来引用,可以这样做:

echo 'Why can'\''t I write '"'"'s between single quotes'   # Why can't I write 's between single quotes

三个被单引号引用的字符串,在这三个字符串之间有一个用转义符转义的单引号,和一个用双引号括起来的单引号。

时间: 2024-11-01 07:53:21

Bash中的变量的相关文章

Linux bash Shell中的变量类型详解

  这篇文章主要介绍了Linux bash Shell中的变量类型详解,变量类型共分为本地变量.局部变量.环境变量.位置变量和特殊变量等,需要的朋友可以参考下 在Linux系统中进行日常运维或者是编写脚本时,变量是再熟悉不过的了,但这些变量都有哪些类型,具体的用法又有哪些差异呢?本文整理分享给大家: 一.bash变量类型: 本地变量 局部变量 环境变量 位置变量 特殊变量(内置) 二.本地变量: varname=value:作用域为整个bash进程可以使用; 变量命名规范: 1. 只能含字母.数

Linux中环境变量配置文件详解

  环境变量是和Shell紧密相关的,用户登录系统后就启动了一个Shell.对于Linux来说一般是bash,但也可以重新设定或切换到其它的 Shell.对于UNIX,可能是CShelll.环境变量是通过Shell命令来设置的,设置好的环境变量又可以被所有当前用户所运行的程序所使用.对于bash这个Shell程序来说,可以通过变量名来访问相应的环境变量,通过export来设置环境变量.下面通过几个实例来说明. 一.系统级: 1)etc/profile:此文件为系统的每个用户设置环境信息,当用户第

Shell中的变量使用小结

  这篇文章主要介绍了Shell中的变量使用小结,本文总结了变量的语法.常见使用形式等内容,并分别给出代码示例,需要的朋友可以参考下 变量的定义,只能以字母和下划线开始,区分大小写,可以包含数字 字母下划线.详见官方手册    代码如下: [root@svn shell_example]# yourname='Linux' [root@svn shell_example]# echo $yourname Linux [root@svn shell_example]# YourName="linu

如何在shell脚本中使用变量

如何在shell脚本中使用变量 在每种编程语言中,变量都扮演了一个重要的角色.在Linux shell脚本编程中,我们使用两种类型的变量:系统定义的变量和用户定义的变量. shell脚本中的变量是用来调用一个数值或者字符值的手段.与正规的编程语言不同的是,shell脚本不要求你去为变量声明一个类型. 在本文中,我们将讨论shell脚本编程中的变量及其类型,以及如何设置和使用这些变量. 系统定义的变量: 这些变量由操作系统(Linux)自身创建并维护,通常它们以大写字母定义,我们可以通过命令"$

Linux中环境变量文件及配置

一.环境变量文件介绍 转自:http://blog.csdn.net/cscmaker/article/details/7261921 Linux中环境变量包括系统级和用户级,系统级的环境变量是每个登录到系统的用户都要读取的系统变量,而用户级的环境变量则是该用户使用系统时加载的环境变量.所以管理环境变量的文件也分为系统级和用户级的,下面贴一个网上找到的讲的比较明白的文件介绍(略作修改)[1]: 1.系统级:(1)/etc/profile:该文件是用户登录时,操作系统定制用户环境时使用的第一个文件

Bash 中的特殊字符大全

Linux下无论如何都是要用到shell命令的,在Shell的实际使用中,有编程经验的很容易上手,但稍微有难度的是shell里面的那些个符号,各种特殊的符号在我们编写Shell脚本的时候如果能够用的好,往往能给我们起到事半功倍的效果,为此,特地将Shell里面的一些符号说明罗列成对照表的形式,以便快速的查找.看看你知道下表中的哪些Shell符号呢? Shell符号及各种解释对照表: Shell符号 使用方法及说明 # 注释符号(Hashmark[Comments]) 1.在shell文件的行首,

Bash中的特殊字符

Bash中,用在脚本和其他地方的字符叫做特殊字符.下面依次举例介绍每个字符的用途. # 行首以#(#!是个例外)开头是注释. # This line is a comment. 注释也可以放在于本行命令的后边. echo "A comment will follow." # 注释在这里. 命令是不能放在同一行上注释的后边的.因为没有办法把注释结束掉,好让同一行上后边的"代码生效",只能够另起一行来使用下一个命令. 在echo中转义的#是不能作为注释的,同样也可以出现

Linux中的变量【2】环境变量

1 环境变量配置文件 主要是定义对系统操作环境生效的系统默认变量,比如PATH.HISTSIZE.PS1(登录提示符).HOSTNAME等默认环境变量. 2 重要配置文件 /etc/profile /etc/profile.d/*.sh ~/.bash_profile ~/.bashrc /etc/bashrc /etc/文件中的变量对所有用户都生效.~文件中的只对当前用户生效. 3 调用顺序 A 通过输入用户名密码进入linux终端,在最终显示命令提示符之前,配置文件的调用顺序如下 1 /et

linux中shell中的变量使用说明

变量说明: $$ Shell本身的PID(ProcessID) $! Shell最后运行的后台Process的PID $? 最后运行的命令的结束代码(返回值) $- 使用Set命令设定的Flag一览 $* 所有参数列表.如"$*"用「"」括起来的情况.以"$1 $2 - $n"的形式输出所有参数. $@ 所有参数列表.如"$@"用「"」括起来的情况.以"$1" "$2" - "