您好, 欢迎来到 !    登录 | 注册 | | 设为首页 | 收藏本站

Shell 变量

1. Shell 变量概述

变量是任何程序或脚本的重要组成部分,变量为程序或脚本访问内存中的可的一块数据提供了简单的方式。

Linux Shell 中的变量可以被指定为任意的数据类型,比如文本字符串或者数值。你也可以通过 Shell 中的变量来改变 Shell 的样式。

接下来就让我们来了解和学习一下 Shell 中的变量吧。

Shell 变量是什么呢,顾名思义,就是可以变化的量,如果有编程基础的读者知道任何程序中都有变量,从我们小时候做数学题,定义的 x 变量,最终给定值,用值替换 x 变量,这就是我们最初接触的变量,它和我们在 Shell 中接触的变量本质上是一致的。

变量在 Shell 中是存储计算器内存的单元,其中存放的值可以改变,当我们在编写 Shell 脚本中,如果一些经常用的字符串或数字我们就可以定义变量,将具体的值赋给这个变量,然后在具体的或脚本中引用这个变量,就相当于拿到了这个值。

我们大概了解了 Shell 变量是什么,那么为什么在 Shell 脚本中需要变量呢?

例如在 Shell 脚本中,我们需要指定目录,脚本内多处了这个目录,现在我们有个需求目录改变了,我们该怎么办呢,在脚本中每个使用该目录的地方都需要改成新的目录,有没有简单的只需要改一处地方呢,这时候就用到了我们的变量,在脚本的全局定义变量例如 BASE_DIR,然后将目录赋值给这个变量,在具体引用的时候利用这个目录的变量,下次需要我们改,只用改最前面这个变量即可。

因此我们使用变量就是为了方便,同时也使得我们的脚本更具灵活性扩展性与后期的可维护性。

2. Shell 变量基本操作

我们知道了 Shell 中变量是什么以及其在 Shell 编写中的重要性,那么让我们先来学习 Shell 变量的基本操作。

在使用 Shell 变量前,需要先定义变量,定义变量的方式有三种:

顾名思义就是直接将值赋值给变量,这种需要注意值中不能包含空白字符

例如:正确的直接赋值变量:DIR=/tmp,其中 DIR 为变量名,/tmp 为值

的直接赋值:STRING=hello Shell,其中 STRINNG 为变量名,hello Shell 为值,其中值包含了空白字符,这种赋值变量就是的。

如果值中为普通字符,那么单引号赋值与双引号赋值没有区别,其可以包含空白字符,但是如果其中包含了变量的使用,那么单引号赋值方式为单引号里面的是什么就什么,此种赋值方式适用于不希望解析变量的场景,仅纯字符串。

例如:

[root@master ~]# echo $PATH/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin[root@master ~]# DIR='$PATH'[root@master ~]# echo $DIR$PATH[root@master ~]# DATE='$(date)'[root@master ~]# echo $DATE$(date)

PATH 为 linux 系统内置的环境变量,DIR 为我们定义的变量,值为单引号引起来的 $PATH,查看其也为 $PATH,同理对于执行 date 命令。

与单引号赋值一样,其也可以包含空白字符,但是与单引号赋值不同的是,双引号赋值可以解析引号内的变量或执行命令,即不是将双引号中的变量名和命令原样,而是解析其中变量的,然后进行。

例如:

[root@master ~]# echo $PATH/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin[root@master ~]# DIR="$PATH"[root@master ~]# echo $DIR/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin[root@master ~]# DATE="$(date)" [root@master ~]# echo $DATE    Sun Mar  :: CST

可以通过与单引号示例对照查看,双引号赋值解析了 PATH 变量的值然后,同理对于执行命令 date

我们知道了变量的定义方式,那么该如何使用变量呢?使用变量非常简单,只需要在定义的变量名前面 $ 即可使用定义的变量

例如:

[root@master ~]# DIR=/tmp[root@master ~]# echo $DIR/tmp

在使用变量中有一种特殊情况,需要我们手动指定变量的边界是什么,此时就需要使用到 {}

[root@master ~]# STRING="hello Shell"[root@master ~]# echo "test $STRINGtest"test 
[root@master ~]# echo "test ${STRING}test"test hello Shelltest

通过示例我们能够看出,不使用 {} 引起来变量,如果变量名后面继续有字符,Shell 无法判断我们的变量边界在哪里,我们推荐在使用变量的时候都带上 {} 减少出错的概率,并且方便我们人为识别变量的边界。

我们已经定义了变量,如果对变量进行更新呢,更新变量重新赋值即可

例如:

[root@master ~]# DIR=/tmp[root@master ~]# echo $DIR/tmp[root@master ~]# DIR=/root[root@master ~]# echo $DIR/root

另外在变量中存在只读变量,顾名思义其为定义好后,只能只读,不能对其进行,使用 readonly 命令可以将变量定义为只读变量

[root@master ~]# readonly STRING="Shell"[root@master ~]# echo ${STRING}Shell[root@master ~]# STRING="test"-bash: STRING: readonly variable[root@master ~]# echo ${STRING}Shell

可以看到我们使用 readonly 定义变量后,对变量进行时候报错,只读变量无法进行。

变量的使用 unset,后就消除了定义的变量,变量被后不能再次使用;unset 命令不能只读变量。

例如

[root@master ~]# DIR=/tmp [root@master ~]# echo "dir is ${DIR}"            dir is /tmp[root@master ~]# unset DIR[root@master ~]# echo "dir is ${DIR}" dir is

3. Shell 变量规范

与其他语言一样,Shell 中变量也需要遵循一定的规范,

变量命名只能使用,数字和下划线,首字母不能以数字开头

正常变量:BASE_DIR,File_Name,AEG3,_DIR 等都是正常的变量

无效变量:1file,#dir

例如

变量名中间不能使用空格或

例如:DIR FILEDIR?FILE 就为无效变量

变量命名不能使用 base 里面的关键字(help 来查看关键字)

Shell 变量大小写敏感,也就是定义为大写的变量名,引用的时候必须完全一致。

例如:DIRNAMEdirname 就是两个不同的变量

变量与值直接使用 “=” 连接,等号两边不能存在空白字符;

例如: dirname = "/tmp" 赋值就是的。

如果值中有空白字符,使用单引号或双引号引起来,双引号对于其中引用的值将会根据其转化,单引号内的特殊字符则一律当字符串进行处理;

例如:DIRNAME="$PATH" 的值为系统 PATH 实际的可执行路径,DIRNAME='$PATH' 的值为 $PATH 的字符串。

可用 \ 来转译变量,让其变为一般字符;

例如:DIRNAME=\$PATH 的值为 $PATH 的字符串。

如果变量的值为指令,可用使用反撇号,或 $() 来引用;

例如:下面两个是一样的

DATE=`date`DATE=$(date)

在脚本中定义普通字符串变量时,应尽量把变量的用双引号括起来;

例如:DIRNAME="/tmp"

单纯数字的变量可以不加引号;

例如:NUM=10

4. 变量的

Shell 的变量有三种,每种都有其不同的作用范围

局部变量,顾名思义其只在 Shell 脚本中定义的变量,或在 Shell 脚本中定义的变量,只能在 Shell 脚本中使用,或只能在 Shell 脚本中使用

例如:

[root@master Shell]# cat local_var.sh #!/bin/bashDIR=/tmp
echo "dir is ${DIR}"[root@master Shell]# bash local_var.sh dir is /tmp[root@master Shell]# echo "dir is ${DIR}"dir is

我们可以看出在脚本内部定义的变量 DIR 只在 local_var 脚本内可以使用,在全局下没有此变量,后期我们学到再来说明中的局部变量。

环境变量为当前 Shell 中定义的临时变量,在当前 Shell 定义的变量可以传递给子 Shell,没有父子关系的 Shell 不能使用此变量,当然可以利用 export 将当前 Shell 的变量传递给其他终端的 Shell 中。

当前 Shell 为父 Shell,在其上运行 bash 就可以进入到子 Shell 中,让我们来看示例

# 在当前Shell中定义变量STR[root@master Shell]# STR="Shell"						[root@master Shell]# echo "hello ${STR}"hello Shell# 运行命令bash进入子Shell[root@master Shell]# bash# 在子Shell中查看没有STR[root@master Shell]# echo "hello ${STR}"hello 
# 子Shell回到父Shell[root@master Shell]# exitexit# 利用export导入环境变量[root@master Shell]# export STR="Shell"# 在此进入子Shell[root@master Shell]# bash# 查看子Shell中已经有了变量STR[root@master Shell]# echo "hello ${STR}"hello Shell

环境变量为临时的,在我们启动终端的时候,系统会从特定的中加载一系列环境变量。

系统中还有一些系统内置的变量,例如 PATHUSER 等,我们可以利用命令 env 或 export 来查看当前 Shell 的环境变量,例如:

[root@master Shell]# envXDG_SESSION_ID=HOSTNAME=master
SELINUX_ROLE_REQUESTED=Shell=/bin/bash
TERM=xterm
HISTSIZE=SSH_CLIENT=.  SELINUX_USE_CURRENT_RANGE=SSH_TTY=/dev/pts/USER=root...# 查看当前Shell[root@master Shell]# echo $Shell/bin/bash# 查看可执行命令的路径[root@master Shell]# echo $PATH/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin# 查看当前系统[root@master Shell]# echo $USERroot

linux 系统的一些内置参数

$Shell  	认 Shel$HOME   	当前家目录$IFS    	内部字段分隔符$LANG   	认语$PATH   	认可执行程序路径$PWD    	当前目录$UID    	当前 ID$USER   	当前$HISTSIZE	历史命令大小,可通过 HISTTIMEFORMAT 变量设置命令执行时间$RANDOM 0 至 32767 的整数$HOSTNAME	主机名

为在当前 Shell 进程中运行的脚本都可以使用该变量,在 Shell 中认定义的变量就是,例如:

[root@master Shell]# cat global_var1.sh #!/bin/bashecho "${STR1}"# 查看STR1变量的STR2="sh"# 定义STR2变量的值为sh[root@master Shell]# cat global_var2.sh #!/bin/bashecho "${STR2}"# 查看STR2变量的[root@master Shell]# STR1="Shell"                    [root@master Shell]# . ./global_var1.sh Shell[root@master Shell]# . ./global_var2.sh sh

我们可以看出利用. 来运行 Shell 脚本,是在当前的 Shell 终端中运行,其变量是在当前 Shell 进程中可以共享的。

5. 实例

我们通过简单编写当前信息的脚本,来展示目前的信息

[root@master Shell_var]# cat login_info.sh  #!/bin/bash# Description: login info scripts# Auth: kaliarch# Email: kaliarch@163.com# function: show user info# Date: 2020-03-08 13:36# Version: 1.0echo "当前系统用为:  ${USER}"echo "当前系统时间:  $(date +"%Y-%m-% %H:%M:")"echo "当前系统Shell: ${Shell}"echo "当前家目录为:  ${HOME}"# 运行脚本查看[root@master Shell_var]# bash login_info.sh 当前系统用为:  root
当前系统时间:  -- ::
当前系统Shell: /bin/bash
当前家目录为:  /root

6. 注意事项

在引用变量是我们遵守规范,带上 {},可以避免不必要的麻烦和坑;

命名变量见名知意,形成有自己一套的命名规范;

学习 Shell 需要多动手实践,将变量的三种类型通过实践真正理解,后期在编写 Shell 的时候可以灵活运用。

7. 小结

变量在我们 Shell 编程中的有这独特的地位,其将我们的一些数据通过一次性的赋值,大大增强了脚本的灵活性与后期可维护性。我们需要通过本章节充分理解 Shell 的基本操作及其种类,在编写 Shell 中灵活运用,遵循定义及使用规范,可以使得我们编写的 Shell 更加友好及健壮。


联系我
置顶