一、定义

所谓的变量,就是就是利用一个特定的"名称"(name)来存取一段可以变化的"值"(value),简单说来就是“用一个名称储存一个数值”。

 

二、设定(=)

1. 如何设定变量

在 bash 中,你可以用"=" 来设定或重新定义变量的内容:

name=value

2. 规则

在设定变量的时侯,得遵守如下规则:

  • 等号左右两边不能使用字符分隔符(IFS),也应避免使用shell的其他元字符(meta charactor)。
  • 变量名称不能使用 $ 符号。
  • 变量名称的第一个字母不能是数字(number)。
  • 变量名称长度不可超过 256 个字母。
  • 变量名称及变量值之大小写是有区别的(case sensitive)。

三、取消设定(unset)

1. 取消变量

要取消一个变量,在bash 中可使用 unset 命令来处理:

unset 变量名

变量一旦经过 unset 取消之后,其结果是将整个变量拿掉,而不仅是取消其变量值,如下两行其实是很不一样的:

$ A=
$ unset A

第一行只是将变量 A 设定为"空值"(null value),但第二行则让变量 A 不在存在。虽然用echo命令输出都是一样的结果,但是在变量替换的时候却有着不同的效果。如:

${unknow=new}:若$unknow没有设定(unset),则使用new作为传回值,同时将unknow赋值为new,若unknow为空值或者非空值,则new对传回值与unknow均不影响,因此对于一个变量,它有只仅有三种状态:

  • 非空值(not null)
  • 空值(null)
  • 不设定(unset)

四、变量替换

1.普通替换

在命令行中使用者可以使用 $ 符号加上变量名称(除了在用 = 号定义变量名称之外),

将变量值给替换出来,然后再重新组建命令行。

比方:

A=ls
B=la
C=/tmp
$A -$B $C

在上面的最后一行命令中,在被执行之前(在输入 CR 字符之前),$符号会对每一个变量作替换处理(将变量值替换出来再重组命令行),最后会得出如下命令行:

ls -la /tmp

若从技术细节来看,shell会依据IFS将command line所输入的文字给拆解为"字段"(word)。然后再针对元字符(meta)先作处理,最后再重组整行command line。这里的 $ 就是 command line 中最经典的 meta 之一了,就是作变量替换的。

2. 变量扩充

我们也可利用命令行的变量替换能力来"扩充"(append)变量值:

A=B:C:D
A=$A:E

这样,第一行我们设定 A 的值为 "B:C:D",然后,第二行再将值扩充为 "B:C:D:E" 。上面的扩充范例,我们使用区隔符号(:)来达到扩充目的,要是没有区隔符号的话,如下是有问题的:

A=BCD
A=$AE

因为第二次是将 A 的值继承 $AE 的提换结果,而非 $A 再加 E ﹗要解决此问题,我们可用更严谨的替换处理:

A=BCD
A=${A}E

上例中,我们使用 {} 将变量名称的范围给明确定义出来,如此一来,我们就可以将 A 的变量值从 BCD 给扩充为 BCDE 。

3. ${}变量替换

(1)一般情况下,$var 与 ${var} 并没有啥不一样。

但是用${ }会比较精确的界定变量名称的范围,但更高级的用法是用来进行变量替换,假设我们定义了一个变量为:

file=/dir1/dir2/dir3/my.file.txt

我们可以用 ${ } 分别替换获得不同的值:

${file#*/}:拿掉第一条 / 及其左边的字符串:dir1/dir2/dir3/my.file.txt
${file##*/}:拿掉最后一条 / 及其左边的字符串:my.file.txt
${file#*.}:拿掉第一个 . 及其左边的字符串:file.txt
${file##*.}:拿掉最后一个 . 及其左边的字符串:txt
${file%/*}:拿掉最后条 / 及其右边的字符串:/dir1/dir2/dir3
${file%%/*}:拿掉第一条 / 及其右边的字符串:(空值)
${file%.*}:拿掉最后一个 . 及其右边的字符串:/dir1/dir2/dir3/my.file
${file%%.*}:拿掉第一个 . 及其右边的字符串:/dir1/dir2/dir3/my

记忆的方法为:

[list]# 是去掉左边(在键盘上 # 在 $ 之左边)
% 是去掉右边(在键盘上 % 在 $ 之右边)
单一符号是最小匹配﹔两个符号是最大匹配。[/list]
${file::}:提取最左边的 个字节:/dir1
${file::}:提取第 个字节右边的连续 个字节:/dir2

(2) 对变量值里的字符串作替换(接上面的例子):

file=/dir1/dir2/dir3/my.file.txt
${file/dir/path}:将第一个 dir 替换为 path:/path1/dir2/dir3/my.file.txt
${file//dir/path}:将全部 dir 提换为 path:/path1/path2/path3/my.file.txt

(3) 针对不同的变量状态赋值(没设定、空值、非空值)

${file-my.file.txt} :假如 $file 没有设定,则使用 my.file.txt 作传回值。(空值及非空值时不作处理)
${file:-my.file.txt} :假如 $file 没有设定或为空值,则使用 my.file.txt 作传回值。 (非空值时不作处理)
${file+my.file.txt} :假如 $file 设为空值或非空值,均使用 my.file.txt 作传回值。(没设定时不作处理)
${file:+my.file.txt} :若 $file 为非空值,则使用 my.file.txt 作传回值。 (没设定及空值时不作处理)
${file=my.file.txt} :若 $file 没设定,则使用 my.file.txt 作传回值,同时将 $file 赋值为my.file.txt 。 (空值及非空值时不作处理)
${file:=my.file.txt} :若 $file 没设定或为空值,则使用 my.file.txt 作传回值,同时将 $file 赋值为 my.file.txt 。(非空值时不作处理)
${file?my.file.txt} :若 $file 没设定,则将 my.file.txt 输出至 STDERR。 (空值及非空值时不作处理)
${file:?my.file.txt} :若 $file 没设定或为空值,则将 my.file.txt 输出至 STDERR。 (非空值时不作处理)

以上的理解在于,你一定要分清楚unset与null及non-null这三种赋值状态。一般而言,:与null有关,若不带:的话,null不受影响,若带:则连null也受影响。还有哦,${#var}可计算出变量值的长度:

${#file} 可得到  ,因为/dir1/dir2/dir3/my.file.txt 刚好是  个字节...

(4) 用来处理数组

一般而言,A="a b c def" 这样的变量只是将 $A 替换为一个单一的字符串,但是改为 A=(a b c def) ,则是将 $A 定义为组数...

bash 的组数替换方法可参考如下方法:

${A[@]} 或 ${A[*]} 可得到 a b c def (全部组数)
${A[]} 可得到 a (第一个组数),${A[]} 则为第二个组数...
${#A[@]} 或 ${#A[*]} 可得到 (全部组数数量)
${#A[]} 可得到1 (即第一个组数(a)的长度),${#A[]}可得到 (第四个组数(def)的长度) A[]=xyz 则是将第四个组数重新定义为 xyz ...

五、export

严格来说,我们在当前shell中所定义的变量,均属于"本地变量"(local variable),只有经过 export 命令的"输出"处理,才能成为环境变量(environment variable):

$ A=B
$ export A

$ export A=B

经过 export 输出处理之后,变量 A 就能成为一个环境变量供其后的命令使用。

六、参考

1. shell十三问

(完)

linux系统中的变量的更多相关文章

  1. Linux系统中的变量PATH

    PATH 作用 在Linux安装一些可执行文件通常要添加路径环境变量PATH,PATH环境变量通俗的讲就是把程序的路径"备案"到系统中,这样执行这些程序时就不需要输入完整路径,直接 ...

  2. Linux 系统中环境变量/etc/profile、/etc/bashrc、~/.bashrc的区别

      /etc/profile./etc/bashrc.~/.bashrc的区别   1> etc目录下存放系统管理和配置文件 (系统配置) etc/profile:  profile为所有的用户 ...

  3. linux系统中给mysql配置环境变量

    安装过程就不写了,记得安装的路径就行,接下来要用到. 修改配置文件 vim /etc/profile 设置环境变量 写一个MYSQL_HOME,值为“mysql的安装路径” 在PATH后面加上$MYS ...

  4. 设置与查看Linux系统中的环境变量

    大家好,我是良许. 大家都知道,在 Linux 系统中,有环境变量和 Shell 变量这两种变量. 环境变量是在程序及其子程序中全局可用的,常常用来储存像默认的文本编辑器或者浏览器,以及可执行文件的路 ...

  5. Linux 系统中的MySQL数据库默认区分大小写

    今天在开发中遇到这么个问题,将连接的数据库改为服务器上的时候(服务器是Linux系统的),程序跑起来后一直出错,总提示数据库的表找不到, 而打开数据库看该表明明是存在的,在我的印象中MySQL数据是不 ...

  6. Linux系统中配置jdk

    在Linux系统下安装jdk 1.到Oracle公司的官网里下载好jdk,网址 http://www.oracle.com/technetwork/java/javase/downloads/jdk8 ...

  7. Linux 系统中用户切换

    1. Linux系统中用户切换的命令为su,语法为: su [-fmp] [-c command] [-s shell] [--help] [--version] [-] [USER [ARG]] 参 ...

  8. Linux系统中“动态库”和“静态库”那点事儿 /etc/ld.so.conf 动态库的后缀为*.so 静态库的后缀为 libxxx.a ldconfig 目录名

    Linux系统中“动态库”和“静态库”那点事儿 /etc/ld.so.conf  动态库的后缀为*.so  静态库的后缀为 libxxx.a   ldconfig   目录名 转载自:http://b ...

  9. Linux系统中“动态库”和“静态库”那点事儿【转】

    转自:http://blog.chinaunix.net/uid-23069658-id-3142046.html 今天我们主要来说说Linux系统下基于动态库(.so)和静态(.a)的程序那些猫腻. ...

随机推荐

  1. k-means算法Java一维实现

    这里的程序稍微有点变形.k_means方法返回K-means聚类的若干中心点.代码: import java.util.ArrayList; import java.util.Collections; ...

  2. 【JS】手机屏幕旋转判断

    function readDeviceOrientation() { if (Math.abs(window.orientation) === 90) { // Landscape alert('横屏 ...

  3. dom4j使用的小例子

    product.xml: <?xml version="1.0" encoding="UTF-8"?> <root> <produ ...

  4. python多标签分类模版

    from sklearn.multioutput import MultiOutputClassifier from sklearn.ensemble import RandomForestClass ...

  5. free 命令结果完全剖析

    free 命令结果完全剖析 total 总物理内存大小. used 已分配的大小,注意,对操作系统来说任何被使用的内存都是used. free 未被分配的物理内存大小. shared 共享内存大小,主 ...

  6. 1095 Cars on Campus

    题意:给出N量车的车牌号,进出的时间,进/出状态.然后给出若干个查询,要求计算在每一查询时刻校园内停着的汽车数量,最后输出这一天中停放时间最长的车辆(若车不止一辆,则按字典序输出)以及停放时间.注:查 ...

  7. 阿里云安装 virtio 驱动

    为避免部分服务器.虚拟机或者云主机的操作系统在阿里云控制台 导入镜像 后,使用该自定义镜像创建的 ECS 实例无法启动,您需要在导入镜像前检查是否需要在源服务器中安装 Xen(pv)或 virtio ...

  8. 用IO字节流复制文件-CopyFileByIo

    import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import ...

  9. scp 远程复制

    1. 上传本地文件到远程机器指定目录 命令: scp /opt/soft/nginx-0.5.38.tar.gz root@192.168.120.204:/opt/soft/scptest 上传本地 ...

  10. CentOS7.6安装mailx

    由于ECS服务器安全问题,发送邮件统一使用SSL模式 安装开始: 第一步:Yum安装mailx:yum install -y mailx 第二步: 创建证书存放目录(如以存在无需创建):mkdir - ...