0


Linux 中变量的取用与设定

优质博文:IT-BLOG-CN

Linux

是一个多人多任务的环境,每个人登录系统都能取得一个

bash shell

,每个人都能够使用

bash

下达

mail

这个指令来接收自己的邮箱等等。问题是,

bash

如何得知你的邮箱是那个文件?这就需要『变量』的帮助。

一、什么是变量

【1】变量的可变性与方便性: 简单的说,变量就是让一个特定的字符串代表不固定的内容。例如,每个账号的邮件预设是以

MAIL

这个变量来进行存取的。当

zzx

用户登录时,他便会去

MAIL

这个变量,而这个变量的内容其实是

/var/spool/mail/zzx

,那如果 bird登录,他的变量

MAIL

的内容就是

/var/spool/mail/bird

。而我们使用信件读取指令

mail

来读取自己的邮箱信件。

**【2】影响

bash

环境操作的变量:** 例如

PATH

变量,你能不能在任何目录下执行某个指令,与

PATH

这个变量有很大关系。例如你下达

ls

这个指令时,系统就是通过

PATH

这个变量里面的内容所记录的路径顺序来搜索指令的。如果搜索完

PATH

变量内的路径还找不到

ls

这个指令时,就会在屏幕上显示

『 command not found 』

的错误讯息了。在

Linux System

下,所有的线程都是需要一个执行码,当正确登入

Linux

后,你就有一个

bash

执行程序,也才真正的经由

bash

来跟系统沟通。由于系统需要一些变量来提供他自己数据的存取(或者是一些环境的设定参数值,例如是否要显示彩色等等),所以就有一些所谓的『环境变量』需要来读入系统中,这些环境例如

PATH

HOME

MAIL

SHELL

等等。为了区别与自定义变量的不同,环境变量通常以大写字符来表示。

**【3】脚本程序设计

(shell script)

的好帮手:** 在个人设定方面,例如我们要写一个大型

script

时,有些数据可能由于用户习惯的不同而有差异,比如说路径,由于路径在

script

被使用的相当多,如果下次换一部主机,都要修改

script

里面的所有路径,那一定很

low

,这个时候就使用变量,而该变量的定义写在最前面,后面相关的路径名称都以变量来取代,那到时候只需要修改一行就等于修改了全部路径,相当方便。

二、变量的取用与设定

**【1】变量的取用

(echo)

:** 利用

echo

就能够读取变量,只需要在变量前加上

$

符号,或者用

${变量}

的方式读取内容。

[root@learnVM 桌面]# echo $PATH
:/usr/lib64/qt-3.3/bin:/usr/local/sbin:/usr/sbin:/sbin:/usr/local/bin:/usr/bin
[root@learnVM 桌面]# echo ${PATH}

【2】变量与变量内容之间如何设定与修改: 用等号

(=)

连接变量与他的内容就好。

[root@learnVM 桌面]# echo $username  
        <=  目前没有查询到任何数据,因为此变量为被设定。
[root@learnVM 桌面]# username=zzx
[root@learnVM 桌面]# echo $username
zzx     <=  为我们设定的username值。

【3】变量的设定规则:
①、等号两边不能直接接空格符。
②、变量名称只能是英文字母与数字,但是开头字符不能时数字。
③、变量内容若有空格符可使用双引号

『"』

或单引号

『'』

将变量内容结合起来。

[root@learnVM 桌面]# test="i am is $username"   <= 双引号的特殊字符如$等,可以保有原本的特性
[root@learnVM 桌面]# echo $test
i am is zzx    <= 对$username进行了解析

[root@learnVM 桌面]# test='i am is $username'   <= 单引号的特殊字符,仅为一般字符,纯文本。
[root@learnVM 桌面]# echo $test
i am is $username   <= 不对$username进行了解析

④、可以使用跳脱字符

『 \ 』

将特殊符号(如:

[Enter]

$

\

,空格符,’ 等)

[root@learnVM 桌面]# test=i\ am\ is\ zzx
[root@learnVM 桌面]# echo $test
i am is zzx

⑤、变量值是一串指令所提供的信息时,可以使用反单引号

『指令』

『$(指令) 』

,例如想要取核心版本:

[root@learnVM 桌面]# version=`uname -r`   
[root@learnVM 桌面]# echo $version
2.6.32-642.el6.x86_64

⑥、若该变量为扩展变量内容时,则可用 “$变量名称” 或 ${变量} 累加内容,如下:

[root@learnVM 桌面]# test=i\ am\ is\ zzx
[root@learnVM 桌面]# test=${test}\ cool  <= 或者使用"$test"\ cool
[root@learnVM 桌面]# echo $test
i am is zzx cool

⑦、若该变量需要在其他子程序执行,则需要

export

来使变量编程环境变量:

『 export 变量名 』

⑧、通常大写的变量是系统默认的变量,自定义的变量一般都为小写。(规则,不遵守也行)
⑨、取消变量的方法使用:unset

[root@learnVM 桌面]# unset test
[root@learnVM 桌面]# echo $test
             <= 变量已被取消,输出的值为空

三、环境变量的功能

**【1】用

env

观察环境变量与常见环境变量说明:** 列出目前的

shell

环境下的所有环境变量与其内容。

[root@learnVM 桌面]# env
ORBIT_SOCKETDIR=/tmp/orbit-root
HOSTNAME=learnVM                     <=这部主机的主机名
IMSETTINGS_INTEGRATE_DESKTOP=yes
SHELL=/bin/bash                      <=目前这个环境下,使用的shell是哪一个程序
TERM=xterm                           <=这个终端机使用的环境是什么类型
HISTSIZE=1000<=记录指令的笔数,默认支持1000
USER=root                            <=使用者的名称
......
env

environment

(环境)的简写,如下部分环境变量。如果使用

export

也会是一样的内容。下面对环境变量进行介绍:

HOME

:代表用户的家目录。我们可以通过

cd ~

去家目录。有很多程序都可能会取用到这个变量的值。

SHELL

:当前使用的

SHELL

是哪只程序,

Linux

预设使用

/bin/bash


MAIL

:当我们使用

mail

这个指令在收信时,系统会去读取邮件邮箱文件

(mailbox)


HISTSIZE

:这个与『历史命令』有关,我们曾下达过的指令可以被系统记录下来,而记录的『笔数』则是由这个值来设定的。

PATH

:就是执行文件搜索的路径,目录与目录之间以冒号分割,由于文件的搜索是依序由

PATH

的变量内的目录来查询的,所以,目录的顺序也是很重要的。

LANG

:这个比较重要,很多讯息都会用到它,例如:当我们启动某些 Perl 的程序语言文件时,他会主动的去分析语系数据文件,如果发现他无法解析的编码语系,就可能产生错误。

RANDOM

:随机数的变量,目前大多数

distributions

都会有随机数生成器,那就是

/dev/random

文件,在

BASH

环境下,这个

RANDOM

变量的内容,介于

0~32767

之间。如果要去

0~9

之间的数值,利用

declare

宣告数值类型,如下:

[root@learnVM 桌面]# declare -i number=$RANDOM*10/32768;echo $number
2<= 此时会随机取0~9之间的数值

【2】用

set

观察所有变量(含环境变量与自定义变量):

bash

可不只有环境变量,还有一些与

bash

操作接口有关的变量,以及用户自己定义的变量存在的。可通过

set

指令查看,

set

除了环境变量之外,还会将其他在

bash

内的变量统统显示出来。

[root@learnVM 桌面]# set
BASH=/bin/bash          <=BASH 主程序放置路径
BASH_VERSINFO=([0]="4"[1]="1"[2]="2"[3]="1"[4]="release"[5]="x86_64-redhat-linux-gnu")<=bash 的版本
COLUMNS=80<=在目前的终端机环境下,使用的字段有几个字符长度
HISTFILE=/root/.bash_history     <=历史命令记录的放置位置,隐藏档。
HISTFILESIZE=1000<=存起来(与上个变量有关)的文件之指令的最大记录笔数
HISTSIZE=1000<=目前环境下,内存中记录的历史命令最大笔数
IFS=$' \t\n'<=预设的分隔符
LINES=24<=目前终端机下的最大行数
PS1='[\u@\h \W]\$ '<=PS1 就是我们系统的命令提示符,例如我的是=[root@learnVM 桌面]
PS2='> '<=如果你使用逃脱符号(\)第二行以后的提示字符

【3】

PS1

(提示字符的设定):命令提示符,当我们每次按下

Enter

键去执行某个指令后,最后要在此出现提示字符时,就会去主动读取这个变量值了,例如我本机的

PS1='[\u@\h \W]\$ ' 

显示的是一种特殊符号,这些特殊符号可以显示不同的信息,每个

distribution

bash

默认的

PS1

变量内容可能有差异,但不要紧,可以通过

man bash

查询

PS1

的相关说明,以理解底下的一些符号的意义。

\d

:可显示出『星期 月 日』的日期格式,如:

“Mon Feb 2”

\H

:完整的主机名。

\h

:仅取主机在第一个小数点之前的名字。

\t

:显示时间,为

24

小时格式的

『HH:MM:SS』

\T

:显示时间,为

12

小时格式的

『HH:MM:SS』

\A

:显示时间,为

24

小时格式的

『HH:MM』

\@

:显示时间,为

12

小时格式的

『am/pm』

\u

:目前使用者的账号名称

\v

BASE

的版本信息

\w

:完整的工作目录名称,由根目录写起的目录名称,所以仅会列出最后一个目录名。

\#

:下达的第几个指令

\$

:提示字符,如果是

root

的话,提示字符为

# 

,否则为

$
CentOS

预设的

PS1

内容:

PS1='[\u@\h \W]\$ '

,这个反斜杠后的数据为

PS1

的特殊功能,与

bash

的变量设定没有关系,现在我们应该都清楚为什么我的命令提示符是:

『root@learnVM 桌面』

,我们也可以修改自己的命令提示符:

[zzx@learnVM home]$ PS1='[\u@\h \w \A #\#]\$'<= \#表示第2次下达的命令,每执行一次命令累加1[zzx@learnVM /home 06:34 #2]$  

【4】

$

(关于本

shell

PID

):钱字号本身也是个变量,表示当前

Shell

的线程代号,既所谓的

PID(Process ID)

。想要知道自己

shell

PID

可以通过

echo $$

获取

PID

号码。

[zzx@learnVM /home 06:34 #2]$echo $$
3405

【5】

(关于上个执行指令的回传值):问号也是一个特殊的变数,在 bash 中这个变量很重要,表示上一个执行的指令所回传的值,当执行某指令时,这些指令都会回传一个执行后的代码。一般来说,如果成功的执行该指令,则会回传一个

0

值,如果执行过程发生错误,就会回传『错误代码』,一般就是以非为

0

的数值来取代。

[zzx@learnVM /home 06:37 #3]$12name=ddd
bash:12name=ddd: command not found
[zzx@learnVM /home 06:44 #4]$echo $?127<=错误代码回传值依据软件而有不同,我们可以利用这个代码来搜索错误的原因

【6】

export

(自定义变量转成环境变量):环境变量与自定义变量的区别,就是该变量能够被子程序继续引用的就是环境变量,反之则为自定义变量。简单介绍下子程序与父程序:当登录

Linux

后,会获取一个

bash

(独立的程序),这个程序的识别使用的是一个称为程序标识符

PID

。接下来在

bash

底下所下达的任何指令都是由这个

bash

所衍生的,那些被下达的指令被称为子程序。
在这里插入图片描述

如上所示,我们在原本的

bash

底下执行另一个

bash

,结果操作的环境接口就会跑到第二个

bash

去(就是子程序),原本的

bash

就是

sleep

这个指令运行的环境就是实现部分,若要回到原本的

bash

去,就只有将第二个

bash

结束掉(下达

exit

或者

logout

)指令。因为子程序仅会继承父程序的环境变量,所以

bash

的自定义变量在进入子程序后就会消失,一直到离开子程序并回到原父程序后,变量才会有生效。那么如何将自定义的变量转化为环境变量啦,就是通过

export

指令实现。

[zzx@learnVM home]$ export 变量名称

如果下达

export

指令就会将所有的『环境变量』绣出来:

[zzx@learnVM home]$ export
declare -x CLASS_PATH=".:/usr/install/jvm/jdk1.8.0_121/lib/dt.jar:/usr/install/jvm/jdk1.8.0_121/lib/tools.jar:/usr/install/jvm/jdk1.8.0_121/jre/lib"
declare -x COLORTERM="gnome-terminal"
declare -x CVS_RSH="ssh"
declare -x DBUS_SESSION_BUS_ADDRESS="unix:abstract=/tmp/dbus-2vt9iZbym4,guid=3aeb40487b94bd413a26d22f0000003a"
declare -x DESKTOP_SESSION="gnome"
declare -x DISPLAY=":0.0"
declare -x GDMSESSION="gnome"
declare -x GDM_KEYBOARD_LAYOUT="us"...........

四、影响显示结果的语系变量(locale)

当我们使用

man command

的方式去查询某个数据的说明文件时,该说明文档的内容可能会因为我们使用的语系不同而产生乱码。另外,利用

ls

查询文件的时间时,也可能会有乱码出现在时间部分。这个问题其实就是语系的问题。目前大多数的

Linux

系统都支持万国码了,也支持大部分的国家语系。我们可以通过

locale

指令查询自己的

Linux

支持多少语系。

[root@learnVM 桌面]# locale -a
zh_TW.big5     <= 大五码的中文编码
zh_TW.euctw
zh_TW.utf8     <= 万国码的中文编码
......

正体中文语系至少支持了两种以上的编码,一种是目前还是很常见的

big5

,另一种则是越来越热门的

utf-8

编码。我们可以通过以下逐一设定每个语系有关的数据变量,但事实是, 如果其他语系变量都没设置,且你有设置

LANG

或者是

LC_ALL

时,则其他的语系变量就会被这两个变量所取代!这也是为什么在

Linux

当中,通常说仅设定

LANG

LC_ALL

两个变量而已。在

Linux

主机的终端机接口

(tty1~tty6)

的环境下,如果设定

『 LANG=zh_TW.utf8 』

这个设定值生效后,使用 man 或者其他讯息输出时,都会出现一堆乱码,尤其是

ls -l

这个参数。

Linux

主机的终端机接口环境下是无法显示像中文这么复杂的编码文字,所以就会产生乱码了。

[root@learnVM 桌面]# locale
LANG=zh_CN.UTF-8
LC_CTYPE="zh_CN.UTF-8"
LC_NUMERIC="zh_CN.UTF-8"
LC_TIME="zh_CN.UTF-8"
LC_COLLATE="zh_CN.UTF-8"
LC_MONETARY="zh_CN.UTF-8"
LC_MESSAGES="zh_CN.UTF-8"
LC_PAPER="zh_CN.UTF-8"
LC_NAME="zh_CN.UTF-8"
LC_ADDRESS="zh_CN.UTF-8"
LC_TELEPHONE="zh_CN.UTF-8"
LC_MEASUREMENT="zh_CN.UTF-8"
LC_IDENTIFICATION="zh_CN.UTF-8"
LC_ALL=

五、变量的有效范围

变量也有使用的范围,则『变量』可否被引用与

export

有关。被

export

后的变量为『环境变量』。为什么环境变量的数据可以被子程序所引用,是因为内存配置的关系。
✔ 当启动一个

shell

,操作系统会分配一记忆区块给 shell 使用,此内存内之变量可让子程序取用。
✔ 若在父程序中利用

export

功能,可以让自定义变量的内容写到上述的记忆区块当中(环境变量)
✔ 当加载另一个 shell 时,子

shell

可以将父

shell

的环境变量所在的记忆区块导入自己的环境变量区块中。

六、变量键盘读取、数组与宣告(read、array、declare)

除了提到的变量设定功能,我们也可以通过键盘输入。就类似于我们执行某些程序时,会提示使用这输入

“yes/no”

之类的讯息。我们还可以宣告这个变量的属性,例如:数组或者是数字等等。

read

:读取来自键盘输入的变量。这个指令最常被用在

shell script

的撰写当中,想要跟使用者对谈就使用该指令。

[root@learnVM /]# read [-pt] variable
选项与参数:
   -p : 后面可以接提示符
   -t : 后面可以接等待的『秒数』这个比较有趣,不会一直等待使用者。

范例一:让用户由键盘输入一内容,将该内容编程名为 atest 的变量
[root@learnVM /]# read atest
this is a test       <= 此时光标会等待你输入
[root@learnVM /]# echo $atest
this is a test       <= 你刚刚输入的数据已经变成一个变量内容

范例二:提示使用者 30 秒内输入自己的大名,将该输入字符串作为名为 named 的变量内容
[root@learnVM /]# read -p "pelse you name"-t 30 names
pelse you name zzx  <= 会有提示字符
[root@learnVM /]# echo $names
zzx                 <= 输入的数据又变成一个变量的内容

declare/typeset

:宣告变量的类型。如果使用

declare

后面并没有接任何参数,那么

bash

就会主动将所有的变量名称与内容统统叫出来,就好像使用

set

一样。

[root@learnVM /]# declare [-aixr] variable
选项与参数:
-a : 将后面名为 variable 的变量定义成为数组(array)类型
-i : 将后面名为 variable 的变量定义为整数数字(integer)类型
-x :用法与 export 一样,就是将后面的 variable 变成环境变量。
-r : 将变量设定成为 readonly 类型,该变量不可被更改内容,也不能unset。

范例一:让sum 进行 1+2+3 的加和
[root@learnVM /]# sum=1+2+3[root@learnVM /]# echo $sum
1+2+3[root@learnVM /]# declare -i sum=1+2+3[root@learnVM /]# echo $sum
6

由于在默认的情况底下

bash

对于变量有几个基本的定义:
● 变量类型默认为『字符串』,所以若不指定变量类型,则

1+2

为一个『字符串』而不是『计算式』。

bash

环境中的数值运算,预设最多仅能达到整数形态,所以

1/3

结果是

0


如果需要非字符串类型的变量,那就得要进行变量的宣告才行。如下继续接受

declare

功能。

范例二:将sum 变为环境变量
[root@learnVM 桌面]# declare -x sum
[root@learnVM 桌面]# export |grep sum
declare -ix sum="6"<= 会出现 i 与 x 的宣告

范例三:将sum 变为只读属性,不可更改
[root@learnVM 桌面]# declare -r sum
[root@learnVM 桌面]# sum=test
bash: sum: readonly variable     <=不允许修改此属性

范例四:将sum 更改为非环境变量的自定义变量
[root@learnVM 桌面]# declare +x sum   <= 将-变成+ 表示【取消】功能,这里 x 表示环境变量
[root@learnVM 桌面]# declare -p sum   <=-p 可以单独列出变量的类型
declare -ir sum="6"<= 只剩下i,r的类型,不具有x(环境变量)类型。

需要注意的是,如果不小心将变量设定为『只读』,通常得要注销再登入才能复原该变量的类型。

✔ 数组

(array)

变量类型:

var[index]=content

:表示数组名为

var

,我们假定数组的内容为

var[1]=1,var[2]=2,var[3]=3

等等,那么

index

就是一些数字。

范例:设定上面提到的 var[1]~ var[3] 的变数
[root@learnVM 桌面]# var[1]="1"[root@learnVM 桌面]# var[2]="2"[root@learnVM 桌面]# var[3]="3"[root@learnVM 桌面]# echo "${var[1]},${var[2]},${var[3]}"1,2,3

七、与文件系统及程序的限制关系(ulimit)

我们知道

Linux

可以同时登陆十个人,如果同时启动十个文件每个文件的大小约

10 MBytes

,主机的内存就需要

10*100*10= 10000MBytes=10GBytes

,系统就会挂点。为了要预防这个情况的发生,所以我们的

bash

是可以『限制用户的某些系统资源』的,包括可以开启的文件数量,可以使用的

CPU

时间,可以使用内存总量等等。可以用

ulimit

进行设置。

[root@learnVM 桌面]# ulimit [-SHacdfltu][配额]
选项与参数:
 -H : hard limit ,严格的设定,必定不能超过这个设定的数值;
 -S :soft limit ,警告的设定,可以超过这个设定值,但是若超过则有警告信息。
                   在设定上,通常 soft 会比 hard 小,例如 soft 80,而hard 100-a :后面不接任何选项与参数,可以列出所有的限制额度
 -c : 当某些程序发生错误时,系统可能会将该程序的内存中的信息写成文件(除错用),
      这种文件就被称为核心文件(core file)。此为限制每个核心文件的最大容量。
 -f : 此 shell 可以建立的最大文件容量(一般可能设定为2GB)单位为 Kbytes
 -d : 程序可使用的最大断裂内存(segment)容量。
 -l : 可用于锁定的内容容量
 -t : 可使用的最大CPU时间(单位为秒)
 -u : 单一用户可以使用的最大程序(process)数量

范例:列出你目前身份(假设为一般账号)的所有限制数据数值

[root@learnVM 桌面]# ulimit -a
core file size(blocks,-c)0<=只要是0就代表么有限制
data seg size(kbytes,-d) unlimited
scheduling priority(-e)0
file size(blocks,-f) unlimited      <=可建立的单一文件大小
pending signals(-i)7334
max locked memory(kbytes,-l)64
max memory size(kbytes,-m) unlimited
open files(-n)1024<=同时可开启的文件数量
pipe size(512 bytes,-p)8
POSIX message queues(bytes,-q)819200
real-time priority(-r)0
stack size(kbytes,-s)10240
cpu time(seconds,-t) unlimited
max user processes(-u)7334
virtual memory(kbytes,-v) unlimited
file locks(-x) unlimited

想要复原

ulimit

的设定最简单的方法就是注销再登入,否则就是得要重新以

ulimit

设定才行。需要注意的是,一般身份使用者如果要以

ulimit

设定

-f

的文件大小,那么他『只能继续减小文件容量,不能增加文件容量』。

八、变量内容的删除、取代与替换(Optional)

【1】变量内容的删除与取代: 具体举例说明:

[root@learnVM 桌面]# test=1234567890[root@learnVM 桌面]# echo ${test#*5}<= test是变量名称,#表示从变量的最前面开始向右删除,且仅删除最短的那个
67890[root@learnVM 桌面]# echo ${test//8/44}  <= 将8 替换为 4412345674490
(*)

表示通配符,取

0

到无穷多个任意字符。从上面 的案例可以看出删除了5之前的所有元素。上面的一个 # 表示删掉最短的那个,那么两个 ## 表示删除最长的那个数据。那么除了上述从前面开始删除

#

之外,还有重后面开始删除的

%

。上述取掉实例中,两个斜线中间的是旧字符串,后面的是新字符串。那么两个双斜线表示的是替换所有符号条件的内容。

【2】变量的测试与内容替换: 通常我们会判断某变量是否存在,如存在使用以有的,若不存在则给予一个常用的设定。举例:

[root@learnVM 桌面]# echo ${username}<= 空白表示username变量不存在
[root@learnVM 桌面]# username=${username-root}[root@learnVM 桌面]# echo $username
root                                           <= 因为username不存在所以赋默认root值
[root@learnVM 桌面]# username=zzx               <=当给其手动赋值zzx后,再是用 *-root
[root@learnVM 桌面]# username=${username-root}[root@learnVM 桌面]# echo $username          
zzx                                             <=会发现默认的 root 不会生效

在大括号内冒号

【:】

的作用,被测试的变量如果设定为空字符串时,就可以用

*-root

中的

root

来替换设定的空字符串的值:
变量设定方式str 没有设定str 为空字符串str 已设定非为空字符串var=${str-expr}var=exprvar=var=$strvar=${str:-expr}var=exprvar=exprvar=$strvar=${str+expr}var=var=exprvar=exprvar=${str:+expr}var=var=var=exprvar=${str=expr}str=expr var=exprstr不变 var=str不变 var=$strvar=${str:=expr}str=expr var=exprstr=expr var=exprstr不变 var=$str

标签: linux chrome 运维

本文转载自: https://blog.csdn.net/zhengzhaoyang122/article/details/139972605
版权归原作者 程序猿进阶 所有, 如有侵权,请联系我们删除。

“Linux 中变量的取用与设定”的评论:

还没有评论