一、定义

所谓的变量,就是就是利用一个特定的"名称"(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. Falcon

    1. JE falcon还需要安装je用来处理jdbc,否则打不开falcon的页面,爆内部错误503,然后看异常信息:Caused by: org.apache.falcon.FalconExcep ...

  2. bzoj 1043 [HAOI2008]下落的圆盘——圆的周长

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1043 算每个圆被它后面的圆盖住了多少圆弧即可.注意判断这个圆完全被后面盖住的情况. #inc ...

  3. Hadoop的简单序列化框架

    Hadoop提供了一个加单的序列化框架API,用于集成各种序列化实现.该框架由Serialization实现. 其中Serialization是一个接口,使用抽象工厂的设计模式,提供了一系列和序列化相 ...

  4. SQLServer中求两个字符串的交集(字符串以符号分隔)

    两个字符串,以特定符号分隔(例如‘,’号),求交集 第一种情况: declare @m varchar(100),@n varchar(100)select @m=',2,3,5,7,8,9,10,' ...

  5. [转载]Linux驱动mmap内存映射

    原文地址:https://www.cnblogs.com/wanghuaijun/p/7624564.html mmap在linux哪里? 什么是mmap? 上图说了,mmap是操作这些设备的一种方法 ...

  6. Hibernate学习6—Hibernate 映射类型

    第一节:基本类型映射 com.cy.model.Book.java: package com.cy.model; import java.sql.Blob; import java.util.Date ...

  7. mysql索引之一:索引基础(B-Tree索引、哈希索引、聚簇索引、全文(Full-text)索引区别)(唯一索引、最左前缀索引、前缀索引、多列索引)

    没有索引时mysql是如何查询到数据的 索引对查询的速度有着至关重要的影响,理解索引也是进行数据库性能调优的起点.考虑如下情况,假设数据库中一个表有10^6条记录,DBMS的页面大小为4K,并存储10 ...

  8. Oracle归档与非归档模式

    一.什么是Oracle归档模式 Oracle数据库有联机重做日志,这个日志是记录对数据库所做的修改,比如插入,删除,更新数据等,对这些操作都会记录在联机重做日志里.一般数据库至少要有2个联机重做日志组 ...

  9. Math对象及相关方法

    Math.abs() 取绝对值 Math.ceil()向上取整 (出现小数点就向上+1) Math.floor()向下取整 Math.round()四舍五入 Math.max(val1,val2,va ...

  10. 一,我的Android Studio 3.0.1 安装过程

    安装成功于20171231的0:46分. 简要记录我的安装过程如下: 一,安装JDK1.8.X 二,安装ANDROID STUDIO.ZIP 三,运行AS,后按提示下载SDK,NDK,必要时设置一下J ...