热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Linux学习Shell的变量功能

什么是变量?简单的说,就是让某一个特定字串代表不固定的内容。变量的可变性与方便性举例来说,我们每个帐号的邮件信箱默认是以MAIL这个变量来

什么是变量?

简单的说,就是让某一个特定字串代表不固定的内容。

  • 变量的可变性与方便性

举例来说,我们每个帐号的邮件信箱默认是以 MAIL 这个变量来进行存取的, 当 dmtsai 这个 使用者登陆时,他便会取得 MAIL 这个变量,而这个变量的内容其实就是/var/spool/mail/dmtsai, 那如果 vbird 登陆呢?他取得的 MAIL 这个变量的内容其实就是 /var/spool/mail/vbird 。 而我们使用信件读取指令 mail 来读取自己的邮件信箱时,这支程序可以直接读取 MAIL 这个变量的内容, 就能够自动的分辨出属于自己的信箱信件 !这 样一来,设计程序的设计师就真的很方便的啦!

输入图片说明

  • 影响 bash 环境操作的变量

由于在 Linux System 下面,所有的线程都是需要一个执行码, 而就 如同上面提到的,你“真正以 shell 来跟 Linux 沟通,是在正确的登陆 Linux 之后!”这个时候 你就有一个 bash 的执行程序,也才可以真正的经由 bash 来跟系统沟通 !而在进入 shell 之前,也正如同上面提到的,由于系统需要一些变量来提供他数据的存取 (或者是一些环境 的设置参数值, 例如是否要显示彩色等等的) ,所以就有一些所谓的“环境变量” 需要来读入 系统中了!这些环境变量例如 PATH、HOME、MAIL、SHELL 等等,都是很重要的, 为了区 别与自订变量的不同,环境变量通常以大写字符来表示呢!

  • 脚本程序设计 (shell script) 的好帮手

这些还都只是系统默认的变量的目的,如果是个人的设置方面的应用呢:例如你要写一个大型的 script 时,有些数据因为可能由于使用者习惯的不同而有差异,比如说路径好了,由于 该路径在 script 被使用在相当多的地方,如果下次换了一部主机,都要修改 script 里面的所有路径。 这个时候如果使用变量,而将该变量的定义写在最前面,后面相 关的路径名称都以变量来取代, 嘿嘿!那么你只要修改一行就等于修改整篇 script 了!方便 的很!所以,良好的程序设计师都会善用变量的定义!

最后我们就简单的对“什么是变量”作个简单定义好了: “变量就是以一组文字或符号等,来取 代一些设置或者是一串保留的数据!”

变量的取用与设置:echo, 变量设置规则, unset

echo 这个指令来取用变量, 但是,变量在被取用时, 前面必须要加上钱字号“ $ ”才行。

  • 变量的取用: echo

[dmtsai@study ~]$ echo $variable
[dmtsai@study ~]$ echo $PATH
/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/dmtsai/.local/bin:/home/dmtsai/bin
[dmtsai@study ~]$ echo ${PATH}

那么我要如何“设置”或者是“修改” 某 个变量的内容啊?很简单啦!用“等号(=)”连接变量与他的内容就好啦!举例来说: 我要将 myname 这个变量名称的内容设置为 VBird ,那么:

[dmtsai&#64;study ~]$ echo ${myname}<&#61;&#61;这里并没有任何数据~因为这个变量尚未被设置!是空的!
[dmtsai&#64;study ~]$ myname&#61;VBird
[dmtsai&#64;study ~]$ echo ${myname}
VBird <&#61;&#61;出现了!因为这个变量已经被设置了!

变量的设置规则:

  • 变量与变量内容以一个等号“&#61;”来链接&#xff0c;如下所示: “myname&#61;VBird”

  • 等号两边不能直接接空白字符&#xff0c;如下所示为错误: “myname &#61; VBird”或“myname&#61;VBird Tsai”

  • 变量名称只能是英文字母与数字&#xff0c;但是开头字符不能是数字&#xff0c;如下为错误: “2myname&#61;VBird”

  • 变量内容若有空白字符可使用双引号“"”或单引号“&#39;”将变量内容结合起来&#xff0c;但
    • 双引号内的特殊字符如 $ 等&#xff0c;可以保有原本的特性&#xff0c;如下所示: “var&#61;"lang is $LANG"”则“echo $var”可得“lang is zh_TW.UTF-8”
    • 单引号内的特殊字符则仅为一般字符 (纯文本)&#xff0c;如下所示: “var&#61;&#39;lang is $LANG&#39;”则“echo $var”可得“lang is $LANG”
  • 可用跳脱字符“  ”将特殊符号(如 [Enter], $, , 空白字符, &#39;等)变成一般字符&#xff0c;如: “myname&#61;VBird Tsai”

  • 在一串指令的执行中&#xff0c;还需要借由其他额外的指令所提供的信息时&#xff0c;可以使用反单引 号“ 指令 ”或 “$(指令)”。特别注意&#xff0c;那个 &#96; 是键盘上方的数字键 1 左边那个按键&#xff0c;而不 是单引号! 例如想要取得核心版本的设置: “version&#61;$(uname -r)”再“echo $version”可得“3.10.0-229.el7.x86_64”

  • 若该变量为扩增变量内容时&#xff0c;则可用 "$变量名称" 或 ${变量} 累加内容&#xff0c;如下所示: “PATH&#61;"$PATH":/home/bin”或“PATH&#61;${PATH}:/home/bin”

  • 若该变量需要在其他子程序执行&#xff0c;则需要以 export 来使变量变成环境变量: “export PATH”

  • 通常大写字符为系统默认变量&#xff0c;自行设置变量可以使用小写字符&#xff0c;方便判断 (纯粹依照 使用者兴趣与嗜好);

  • 取消变量的方法为使用 unset :“unset 变量名称”例如取消 myname 的设置: “unset myname”

范例 :

范例一 : 设置一变量 name &#xff0c;且内容为 VBird
[dmtsai&#64;study ~]$ 12name&#61;VBird
bash: 12name&#61;VBird: command not found... <&#61;&#61;屏幕会显示错误!因为不能以数字开头!
[dmtsai&#64;study ~]$ name &#61; VBird <&#61;&#61;还是错误!因为有空白!
[dmtsai&#64;study ~]$ name&#61;VBird <&#61;&#61;OK 的啦!范例二:承上题&#xff0c;若变量内容为 VBird&#39;s name 呢&#xff0c;就是变量内容含有特殊符号时:
[dmtsai&#64;study ~]$ name&#61;VBird&#39;s name
# 单引号与双引号必须要成对&#xff0c;在上面的设置中仅有一个单引号&#xff0c;因此当你按下 enter 后&#xff0c;
# 你还可以继续输入变量内容。这与我们所需要的功能不同&#xff0c;失败啦!
# 记得&#xff0c;失败后要复原请按下 [ctrl]-c 结束!
[dmtsai&#64;study ~]$ name&#61;"VBird&#39;s name" <&#61;&#61;OK 的啦!
# 指令是由左边向右找→&#xff0c;先遇到的引号先有用&#xff0c;因此如上所示&#xff0c; 单引号变成一般字符!
[dmtsai&#64;study ~]$ name&#61;&#39;VBird&#39;s name&#39; <&#61;&#61;失败的啦!
# 因为前两个单引号已成对&#xff0c;后面就多了一个不成对的单引号了!因此也就失败了!
[dmtsai&#64;study ~]$ name&#61;VBird\&#39;s\ name <&#61;&#61;OK 的啦!
# 利用反斜线 (\) 跳脱特殊字符&#xff0c;例如单引号与空白键&#xff0c;这也是 OK 的啦!范例三:我要在 PATH 这个变量当中“累加”:/home/dmtsai/bin 这个目录
[dmtsai&#64;study ~]$ PATH&#61;$PATH:/home/dmtsai/bin
[dmtsai&#64;study ~]$ PATH&#61;"$PATH":/home/dmtsai/bin
[dmtsai&#64;study ~]$ PATH&#61;${PATH}:/home/dmtsai/bin
# 上面这三种格式在 PATH 里头的设置都是 OK 的!但是下面的例子就不见得 !范例四:承范例三&#xff0c;我要将 name 的内容多出 "yes" 呢?
[dmtsai&#64;study ~]$ name&#61;$nameyes
# 知道了吧?如果没有双引号&#xff0c;那么变量成了啥?name 的内容是 $nameyes 这个变量!
# 呵呵!我们可没有设置过 nameyes 这个变量呐!所以&#xff0c;应该是下面这样才对!
[dmtsai&#64;study ~]$ name&#61;"$name"yes
[dmtsai&#64;study ~]$ name&#61;${name}yes <&#61;&#61;以此例较佳!范例五:如何让我刚刚设置的 name&#61;VBird 可以用在下个 shell 的程序?
[dmtsai&#64;study ~]$ name&#61;VBird
[dmtsai&#64;study ~]$ bash <&#61;&#61;进入到所谓的子程序
[dmtsai&#64;study ~]$ echo $name <&#61;&#61;子程序:再次的 echo 一下;
<&#61;&#61; 并没有刚刚设置的内容喔!
[dmtsai&#64;study ~]$ exit <&#61;&#61;子程序:离开这个子程序
[dmtsai&#64;study ~]$ export name
[dmtsai&#64;study ~]$ bash <&#61;&#61;进入到所谓的子程序
[dmtsai&#64;study ~]$ echo $name <&#61;&#61;子程序:在此执行!
VBird <&#61;&#61;看吧!出现设置值了!
[dmtsai&#64;study ~]$ exit <&#61;&#61;子程序:离开这个子程序

在一般的状态下&#xff0c;父程序的自订变量是无法在子程序内使用的。但是 通过 export 将变量变成环境变量后&#xff0c;就能够在子程序下面应用了。

范例六:如何进入到您目前核心的模块目录?
[dmtsai&#64;study ~]$ cd /lib/modules/&#96;uname -r&#96;/kernel
[dmtsai&#64;study ~]$ cd /lib/modules/$(uname -r)/kernel # 以此例较佳!范例七:取消刚刚设置的 name 这个变量内容
[dmtsai&#64;study ~]$ unset name

环境变量的功能

  • 用 env 观察环境变量与常见环境变量说明

范例一:列出目前的 shell 环境下的所有环境变量与其内容。
[dmtsai&#64;study ~]$ env
HOSTNAME&#61;study.centos.vbird <&#61;&#61; 这部主机的主机名称
TERM&#61;xterm <&#61;&#61; 这个终端机使用的环境是什么类型
SHELL&#61;/bin/bash <&#61;&#61; 目前这个环境下&#xff0c;使用的 Shell 是哪一个程序?
HISTSIZE&#61;1000 <&#61;&#61; “记录指令的笔数”在 CentOS 默认可记录 1000 笔
OLDPWD&#61;/home/dmtsai <&#61;&#61; 上一个工作目录的所在
LC_ALL&#61;en_US.utf8 <&#61;&#61; 由于语系的关系&#xff0c;鸟哥偷偷丢上来的一个设置
USER&#61;dmtsai <&#61;&#61; 使用者的名称啊!
LS_COLORS&#61;rs&#61;0:di&#61;01;34:ln&#61;01;36:mh&#61;00:pi&#61;40;33:so&#61;01;35:do&#61;01;35:bd&#61;40;33;01:cd&#61;40;33;01
or&#61;40;31;01:mi&#61;01;05;37;41:su&#61;37;41:sg&#61;30;43:ca&#61;30;41:tw&#61;30;42:ow&#61;34;42:st&#61;37;44:ex&#61;01;32
*.tar&#61;01... <&#61;&#61; 一些颜色显示
MAIL&#61;/var/spool/mail/dmtsai <&#61;&#61; 这个使用者所取用的 mailbox 位置
PATH&#61;/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/dmtsai/.local/bin:/home/dmtsai/bin
PWD&#61;/home/dmtsai <&#61;&#61; 目前使用者所在的工作目录 (利用 pwd 取出!)
LANG&#61;zh_TW.UTF-8 <&#61;&#61; 这个与语系有关&#xff0c;下面会再介绍!
HOME&#61;/home/dmtsai <&#61;&#61; 这个使用者的主文件夹啊!
LOGNAME&#61;dmtsai <&#61;&#61; 登陆者用来登陆的帐号名称
_&#61;/usr/bin/env <&#61;&#61; 上一次使用的指令的最后一个参数(或指令本身)

  • HOME 代表使用者的主文件夹。还记得我们可以使用 cd ~ 去到自己的主文件夹吗?或者 利用 cd 就可以直接回到使用者主文件夹了。那就是取用这个变量啦~ 有很多程序都可能 会取用到这个变量的值!

  • SHELL 告知我们&#xff0c;目前这个环境使用的 SHELL 是哪支程序? Linux 默认使用 /bin/bash!

  • HISTSIZE 这个与“历史命令”有关&#xff0c;亦即是&#xff0c; 我们曾经下达过的指令可以被系统记录下来&#xff0c;而记录的“笔数”则是由这个值来设置的。

  • MAIL 当我们使用 mail 这个指令在收信时&#xff0c;系统会去读取的邮件信箱文件 (mailbox)。

  • PATH 就是可执行文件搜寻的路径啦~目录与目录中间以冒号(:)分隔&#xff0c; 由于文件的搜 寻是依序由 PATH 的变量内的目录来查询&#xff0c;所以&#xff0c;目录的顺序也是重要的喔。

  • LANG 这个重要!就是语系数据 ~很多讯息都会用到他&#xff0c; 举例来说&#xff0c;当我们在启动某 些 perl 的程序语言文件时&#xff0c;他会主动的去分析语系数据文件&#xff0c; 如果发现有他无法解析的 编码语系&#xff0c;可能会产生错误喔!一般来说&#xff0c;我们中文编码通常是 zh_TW.Big5 或者是 zh_TW.UTF-8&#xff0c;这两个编码偏偏不容易被解译出来&#xff0c;所以&#xff0c;有的时候&#xff0c;可能需要修订一 下语系数据。 这部分我们会在下个小节做介绍的!

  • RANDOM 这个玩意儿就是“随机乱数”的变量啦!目前大多数的 distributions 都会有乱数 产生器&#xff0c;那就是 /dev/random 这个文件。 我们可以通过这个乱数文件相关的变量 ($RANDOM) 来随机取得乱数值喔。在 BASH 的环境下&#xff0c;这个 RANDOM 变量的内 容&#xff0c;介于 0~32767 之间&#xff0c;所以&#xff0c;你只要 echo $RANDOM 时&#xff0c;系统就会主动的随机取出 一个介于 0~32767 的数值。万一我想要使用 0~9 之间的数值呢?呵呵~利用 declare 宣 告数值类型&#xff0c; 然后这样做就可以了:

[dmtsai&#64;study ~]$ declare -i number&#61;$RANDOM*10/32768 ; echo $number
8 <&#61;&#61; 此时会随机取出 0~9 之间的数值喔!

  • 用 set 观察所有变量 (含环境变量与自订变量)

[dmtsai&#64;study ~]$ set
BASH&#61;/bin/bash <&#61;&#61; bash 的主程序放置路径
BASH_VERSINFO&#61;([0]&#61;"4" [1]&#61;"2" [2]&#61;"46" [3]&#61;"1" [4]&#61;"release" [5]&#61;"x86_64-redhat-linux-gnu")
BASH_VERSION&#61;&#39;4.2.46(1)-release&#39; <&#61;&#61; 这两行是 bash 的版本啊!
COLUMNS&#61;90 <&#61;&#61; 在目前的终端机环境下&#xff0c;使用的字段有几个字符长度
HISTFILE&#61;/home/dmtsai/.bash_history <&#61;&#61; 历史命令记录的放置文件&#xff0c;隐藏文件
HISTFILESIZE&#61;1000 <&#61;&#61; 存起来(与上个变量有关)的文件之指令的最大纪录笔数。
HISTSIZE&#61;1000 <&#61;&#61; 目前环境下&#xff0c;内存中记录的历史命令最大笔数。
IFS&#61;$&#39; \t\n&#39; <&#61;&#61; 默认的分隔符号
LINES&#61;20 <&#61;&#61; 目前的终端机下的最大行数
MACHTYPE&#61;x86_64-redhat-linux-gnu <&#61;&#61; 安装的机器类型
OSTYPE&#61;linux-gnu <&#61;&#61; 操作系统的类型!
PS1&#61;&#39;[\u&#64;\h \W]\$ &#39; <&#61;&#61; PS1 就厉害了。这个是命令提示字符&#xff0c;也就是我们常见的
[root&#64;www ~]# 或 [dmtsai ~]$ 的设置值啦!可以更动的
PS2&#61;&#39;> &#39; <&#61;&#61; 如果你使用跳脱符号 (\) 第二行以后的提示字符也
$ <&#61;&#61; 目前这个 shell 所使用的 PID
? <&#61;&#61; 刚刚执行完指令的回传值。
...
# 有许多可以使用的函数库功能被鸟哥取消 !请自行查阅!

  • PS1:(提示字符的设置)

这是 PS1 (数字的 1 不是英文字母)&#xff0c;这个东西就是我们的“命令提示字符”喔! 当我们每次 按下 [Enter] 按键去执行某个指令后&#xff0c;最后要再次出现提示字符时&#xff0c; 就会主动去读取这个变量值了。

  • \d :可显示出“星期 月 日”的日期格式&#xff0c;如:"Mon Feb 2"
  • \H :完整的主机名称。举例来说&#xff0c;鸟哥的练习机为“study.centos.vbird”
  • \h :仅取主机名称在第一个小数点之前的名字&#xff0c;如鸟哥主机则为“study”后面省略
  • \t :显示时间&#xff0c;为 24 小时格式的“HH:MM:SS”
  • \T :显示时间&#xff0c;为 12 小时格式的“HH:MM:SS”
  • \A :显示时间&#xff0c;为 24 小时格式的“HH:MM”
  • &#64; :显示时间&#xff0c;为 12 小时格式的“am/pm”样式
  • \u :目前使用者的帐号名称&#xff0c;如“dmtsai”;
  • \v :BASH 的版本信息&#xff0c;如鸟哥的测试主机版本为 4.2.46(1)-release&#xff0c;仅取“4.2”显示 \w :完整的工作目录名称&#xff0c;由根目录写起的目录名称。但主文件夹会以 ~ 取代;
  • \W :利用 basename 函数取得工作目录名称&#xff0c;所以仅会列出最后一个目录名。
  • #:下达的第几个指令。
  • $ :提示字符&#xff0c;如果是 root 时&#xff0c;提示字符为 # &#xff0c;否则就是 $~

  • $:(关于本 shell 的 PID)

钱字号本身也是个变量喔!这个咚咚代表的是“目前这个 Shell 的线程代号”&#xff0c;亦即是所谓的 PID (Process ID)。

  • ?:(关于上个执行指令的回传值)

这个变量 是:“上一个执行的指令所回传的值”&#xff0c; 上面这句话的重点是“上一个指令”与“回传值”两个地 方。当我们执行某些指令时&#xff0c; 这些指令都会回传一个执行后的代码。一般来说&#xff0c;如果成功的 执行该指令&#xff0c; 则会回传一个 0 值&#xff0c;如果执行过程发生错误&#xff0c;就会回传“错误代码”才对!一般 就是以非为 0 的数值来取代。 我们以下面的例子来看看:

[dmtsai&#64;study ~]$ echo $SHELL
/bin/bash <&#61;&#61;可顺利显示!没有错误!
[dmtsai&#64;study ~]$ echo $?
0 <&#61;&#61;因为没问题&#xff0c;所以回传值为 0
[dmtsai&#64;study ~]$ 12name&#61;VBird
bash: 12name&#61;VBird: command not found... <&#61;&#61;发生错误了!bash回报有问题
[dmtsai&#64;study ~]$ echo $?
127 <&#61;&#61;因为有问题&#xff0c;回传错误代码(非为0)
# 错误代码回传值依据软件而有不同&#xff0c;我们可以利用这个代码来搜寻错误的原因喔!
[dmtsai&#64;study ~]$ echo $?
0
# 咦!怎么又变成正确了?这是因为 "?" 只与“上一个执行指令”有关&#xff0c;
# 所以&#xff0c;我们上一个指令是执行“ echo $? ”&#xff0c;当然没有错误&#xff0c;所以是 0 没错!

  • OSTYPE, HOSTTYPE, MACHTYPE:(主机硬件与核心的等级)

目前个人计算机的 CPU 主要 分为 32/64 位&#xff0c;其中 32 位又可分为 i386, i586, i686&#xff0c;而 64 位则称为 x86_64。

  • export: 自订变量转成环境变量

谈了 env 与 set 现在知道有所谓的环境变量与自订变量&#xff0c;那么这两者之间有啥差异呢?其实 这两者的差异在于“ 该变量是否会被子程序所继续引用”。

当你登陆 Linux 并取得一个 bash 之后&#xff0c;你的 bash 就是一个独立的程序&#xff0c;这个程序的识别使 用的是一个称为程序识别码&#xff0c;被称为 PID 的就是。 接下来你在这个 bash 下面所下达的任何 指令都是由这个 bash 所衍生出来的&#xff0c;那些被下达的指令就被称为子程序了。

如你想要让变量内容继续的在子程序中使用&#xff0c;那么就请执行:

[dmtsai&#64;study ~]$ export 变量名称

如果仅下达 export 而没有接变量时&#xff0c;那么此时将会把所有的“环境变 量”秀出来!例如:

[dmtsai&#64;study ~]$ export
declare -x HISTSIZE&#61;"1000"
declare -x HOME&#61;"/home/dmtsai"
declare -x HOSTNAME&#61;"study.centos.vbird"
declare -x LANG&#61;"zh_TW.UTF-8"
declare -x LC_ALL&#61;"en_US.utf8"

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

Linux 到底支持了多少的语系呢?这可以由 locale 这个指令来查询到喔!

[dmtsai&#64;study ~]$ locale -a
....(前面省略)....
zh_TW
zh_TW.big5 <&#61;&#61;大五码的中文编码
zh_TW.euctw
zh_TW.utf8 <&#61;&#61;万国码的中文编码
zu_ZA
zu_ZA.iso88591
zu_ZA.utf8

我们如何修订这些编码呢?其实可以通过下面这些变量:

[dmtsai&#64;study ~]$ locale <&#61;&#61;后面不加任何选项与参数即可!
LANG&#61;en_US <&#61;&#61;主语言的环境
LC_CTYPE&#61;"en_US" <&#61;&#61;字符(文字)辨识的编码
LC_NUMERIC&#61;"en_US" <&#61;&#61;数字系统的显示讯息
LC_TIME&#61;"en_US" <&#61;&#61;时间系统的显示数据
LC_COLLATE&#61;"en_US" <&#61;&#61;字串的比较与排序等
LC_MONETARY&#61;"en_US" <&#61;&#61;币值格式的显示等
LC_MESSAGES&#61;"en_US" <&#61;&#61;讯息显示的内容&#xff0c;如功能表、错误讯息等
LC_ALL&#61; <&#61;&#61;整体语系的环境
....(后面省略)....

基本上&#xff0c;你可以逐一设置每个与语系有关的变量数据&#xff0c;但事实上&#xff0c;如果其他的语系变量都未 设置&#xff0c; 且你有设置 LANG 或者是 LC_ALL 时&#xff0c;则其他的语系变量就会被这两个变量所取代! 这也是为什么我们在 Linux 当中&#xff0c;通常说明仅设置 LANG 或 LC_ALL 这两个变量而已&#xff0c;因为他是最主要的设置变量!

你当然可以让每个使用者自己去调整自己喜好的语系&#xff0c;但是整体系统默认的语系定义在哪里 呢? 其实就是在 /etc/locale.conf。这个文件在 CentOS 7.x 的内容有点像这样:

[dmtsai&#64;study ~]$ cat /etc/locale.conf
LANG&#61;zh_TW.utf8
LC_NUMERIC&#61;zh_TW.UTF-8
LC_TIME&#61;zh_TW.UTF-8
LC_MONETARY&#61;zh_TW.UTF-8
LC_PAPER&#61;zh_TW.UTF-8
LC_MEASUREMENT&#61;zh_TW.UTF-8

变量的有效范围

被 export 后的变量&#xff0c;我们可以称他为“环境变量”! 环境变量可以被子程序所引 用&#xff0c;但是其他的自订变量内容就不会存在于子程序中。

变量键盘读取、阵列与宣告: read, array, declare

  • read

要读取来自键盘输入的变量&#xff0c;就是用 read 这个指令了。这个指令最常被用在 shell script 的撰 写当中&#xff0c; 想要跟使用者对谈?用这个指令就对了。

[dmtsai&#64;study ~]$ read [-pt] variable
选项与参数:-p :后面可以接提示字符!-t :后面可以接等待的“秒数!”这个比较有趣~不会一直等待使用者啦!范例一:让使用者由键盘输入一内容&#xff0c;将该内容变成名为 atest 的变量[dmtsai&#64;study ~]$ read atestThis is a test <&#61;&#61;此时光标会等待你输入!请输入左侧文字看看[dmtsai&#64;study ~]$ echo ${atest}This is a test <&#61;&#61;你刚刚输入的数据已经变成一个变量内容!范例二:提示使用者 30 秒内输入自己的大名&#xff0c;将该输入字串作为名为 named 的变量内容
[dmtsai&#64;study ~]$ read -p "Please keyin your name: " -t 30 named
Please keyin your name: VBird Tsai <&#61;&#61;注意看&#xff0c;会有提示字符喔!
[dmtsai&#64;study ~]$ echo ${named}
VBird Tsai <&#61;&#61;输入的数据又变成一个变量的内容了!

  • declare / typeset

eclare 或 typeset 是一样的功能&#xff0c;就是在“宣告变量的类型”。如果使用 declare 后面并没有接 任何参数&#xff0c;那么 bash 就会主动的将所有的变量名称与内容通通叫出来&#xff0c;就好像使用 set 一样。

[dmtsai&#64;study ~]$ declare [-aixr] variable
选项与参数:-a :将后面名为 variable 的变量定义成为阵列 (array) 类型-i :将后面名为 variable 的变量定义成为整数数字 (integer) 类型-x :用法与 export 一样&#xff0c;就是将后面的 variable 变成环境变量;-r :将变量设置成为 readonly 类型&#xff0c;该变量不可被更改内容&#xff0c;也不能 unset范例一:让变量 sum 进行 100&#43;300&#43;50 的加总结果
[dmtsai&#64;study ~]$ sum&#61;100&#43;300&#43;50
[dmtsai&#64;study ~]$ echo ${sum}
100&#43;300&#43;50 <&#61;&#61;咦!怎么没有帮我计算加总?因为这是文字体态的变量属性啊!
[dmtsai&#64;study ~]$ declare -i sum&#61;100&#43;300&#43;50
[dmtsai&#64;study ~]$ echo ${sum}
450

由于在默认的情况下面&#xff0c; bash 对于变量有几个基本的定义:

  • 变量类型默认为“字串”&#xff0c;所以若不指定变量类型&#xff0c;则 1&#43;2 为一个“字串”而不是“计算式”。 所以上述第一个执行的结果才会出现那个情况的;
  • bash 环境中的数值运算&#xff0c;默认最多仅能到达整数形态&#xff0c;所以 1/3 结果是 0;

下面继续来玩些其他的 declare 功能。

范例二:将 sum 变成环境变量
[dmtsai&#64;study ~]$ declare -x sum
[dmtsai&#64;study ~]$ export | grep sum
declare -ix sum&#61;"450" <&#61;&#61;果然出现了!包括有 i 与 x 的宣告!范例三:让 sum 变成只读属性&#xff0c;不可更动!
[dmtsai&#64;study ~]$ declare -r sum
[dmtsai&#64;study ~]$ sum&#61;tesgting
-bash: sum: readonly variable范例四:让 sum 变成非环境变量的自订变量吧!
[dmtsai&#64;study ~]$ declare &#43;x sum <&#61;&#61; 将 - 变成 &#43; 可以进行“取消”动作
[dmtsai&#64;study ~]$ declare -p sum <&#61;&#61; -p 可以单独列出变量的类型
declare -ir sum&#61;"450"

  • 阵列 (array) 变量类型

在 bash 里头&#xff0c;阵列的设置方式是:

var[index]&#61;content

与文件系统及程序的限制关系: ulimit

[dmtsai&#64;study ~]$ ulimit [-SHacdfltu] [配额]
选项与参数:
-H :hard limit &#xff0c;严格的设置&#xff0c;必定不能超过这个设置的数值;
-S :soft limit &#xff0c;警告的设置&#xff0c;可以超过这个设置值&#xff0c;但是若超过则有警告讯息。
在设置上&#xff0c;通常 soft 会比 hard 小&#xff0c;举例来说&#xff0c;soft 可设置为 80 而 hard
设置为 100&#xff0c;那么你可以使用到 90 (因为没有超过 100)&#xff0c;但介于 80~100 之间时&#xff0c;
系统会有警告讯息通知你!
-a :后面不接任何选项与参数&#xff0c;可列出所有的限制额度;
-c :当某些程序发生错误时&#xff0c;系统可能会将该程序在内存中的信息写成文件(除错用)&#xff0c;
这种文件就被称为核心文件(core file)。此为限制每个核心文件的最大容量。
-f :此 shell 可以创建的最大文件大小(一般可能设置为 2GB)单位为 KBytes
-d :程序可使用的最大断裂内存(segment)容量;
-l :可用于锁定 (lock) 的内存量
-t :可使用的最大 CPU 时间 (单位为秒)
-u :单一使用者可以使用的最大程序(process)数量。范例一:列出你目前身份(假设为一般帐号)的所有限制数据数值
[dmtsai&#64;study ~]$ ulimit -a
core file size (blocks, -c) 0 <&#61;&#61;只要是 0 就代表没限制
data seg size (kBytes, -d) unlimited
scheduling priority (-e) 0
file size (blocks, -f) unlimited <&#61;&#61;可创建的单一文件的大小
pending signals (-i) 4903
max locked memory (kBytes, -l) 64
max memory size (kBytes, -m) unlimited
open files (-n) 1024 <&#61;&#61;同时可打开的文件数量
pipe size (512 Bytes, -p) 8
POSIX message queues (Bytes, -q) 819200
real-time priority (-r) 0
stack size (kBytes, -s) 8192
cpu time (seconds, -t) unlimited
max user processes (-u) 4096
virtual memory (kBytes, -v) unlimited
file locks (-x) unlimited范例二:限制使用者仅能创建 10MBytes 以下的容量的文件
[dmtsai&#64;study ~]$ ulimit -f 10240
[dmtsai&#64;study ~]$ ulimit -a &#124; grep &#39;file size&#39;
core file size (blocks, -c) 0
file size (blocks, -f) 10240 <&#61;&#61;最大量为10240Kbyes&#xff0c;相当10MBytes[dmtsai&#64;study ~]$ dd if&#61;/dev/zero of&#61;123 bs&#61;1M count&#61;20
File size limit exceeded (core dumped) <&#61;&#61;尝试创建 20MB 的文件&#xff0c;结果失败了![dmtsai&#64;study ~]$ rm 123 <&#61;&#61;赶快将这个文件删除 !同时你得要登出再次的登陆才能解开 10M 的限制

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

  • 变量内容的删除与取代

变量的内容可以很简单的通过几个咚咚来进行删除喔!我们使用 PATH 这个变量的内容来做 测试好了。 请你依序进行下面的几个例子来玩玩&#xff0c;比较容易感受的到在这里想要表达的意义:

范例一:先让小写的 path 自订变量设置的与 PATH 内容相同
[dmtsai&#64;study ~]$ path&#61;${PATH}
[dmtsai&#64;study ~]$ echo ${path}
/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/dmtsai/.local/bin:/home/dmtsai/bin范例二:假设我不喜欢 local/bin&#xff0c;所以要将前 1 个目录删除掉&#xff0c;如何显示?
[dmtsai&#64;study ~]$ echo ${path#/*local/bin:}
/usr/bin:/usr/local/sbin:/usr/sbin:/home/dmtsai/.local/bin:/home/dmtsai/bin

上面这个范例很有趣的!他的重点可以用下面这张表格来说明:

${variable#/*local/bin:}上面的特殊字体部分是关键字!用在这种删除模式所必须存在的${variable#/*local/bin:}这就是原本的变量名称&#xff0c;以上面范例二来说&#xff0c;这里就填写 path 这个“变量名称”啦!${variable#/*local/bin:}这是重点!代表“从变量内容的最前面开始向右删除”&#xff0c;且仅删除最短的那个${variable#/*local/bin:}代表要被删除的部分&#xff0c;由于 # 代表由前面开始删除&#xff0c;所以这里便由开始的 / 写起。需要注意的是&#xff0c;我们还可以通过万用字符 * 来取代 0 到无穷多个任意字符

这样了解了 # 的功能了吗?接下来让我们来看看下面的范例三!

范例三 : 我想要删除前面所有的目录&#xff0c;仅保留最后一个目录
[dmtsai&#64;study ~]$ echo ${path#/*:}
/usr/bin:/usr/local/sbin:/usr/sbin:/home/dmtsai/.local/bin:/home/dmtsai/bin
# 由于一个 # 仅删除掉最短的那个&#xff0c;因此他删除的情况可以用下面的删除线来看:
# /usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/dmtsai/.local/bin:/home/dmtsai/bindmtsai&#64;study ~]$ echo ${path##/*:}
/home/dmtsai/bin
# /usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/dmtsai/.local/bin:/home/dmtsai/bin

#与##就分别代表:

  • #&#xff1a;符合取代文字的“最短的”那一個&#xff1b;
  • ##&#xff1a;符合取代文字的“最長的”那一個

如果想要“从后面向前删除变量内容”呢? 这个 时候就得使用百分比 (%) 符号了!来看看范例四怎么做吧!

范例四:我想要删除最后面那个目录&#xff0c;亦即从 : 到 bin 为止的字串
[dmtsai&#64;study ~]$ echo ${path%:*bin}
/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/dmtsai/.local/bin
# 注意啊!最后面一个目录不见去!
# 这个 % 符号代表由最后面开始向前删除!所以上面得到的结果其实是来自如下:
# /usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/dmtsai/.local/bin:/home/dmtsai/bin范例五:那如果我只想要保留第一个目录呢?
[dmtsai&#64;study ~]$ echo ${path%%:*bin}
/usr/local/bin
# 同样的&#xff0c; %% 代表的则是最长的符合字串&#xff0c;所以结果其实是来自如下:
# /usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/dmtsai/.local/bin:/home/dmtsai/bin

了解了删除功能后&#xff0c;接下来谈谈取代吧!

范例六:将 path 的变量内容内的 sbin 取代成大写 SBIN:
[dmtsai&#64;study ~]$ echo ${path/sbin/SBIN}
/usr/local/bin:/usr/bin:/usr/local/SBIN:/usr/sbin:/home/dmtsai/.local/bin:/home/dmtsai/bin
# 这个部分就容易理解的多了!关键字在于那两个斜线&#xff0c;两斜线中间的是旧字串
# 后面的是新字串&#xff0c;所以结果就会出现如上述的特殊字体部分 ![dmtsai&#64;study ~]$ echo ${path//sbin/SBIN}
/usr/local/bin:/usr/bin:/usr/local/SBIN:/usr/SBIN:/home/dmtsai/.local/bin:/home/dmtsai/bin
# 如果是两条斜线&#xff0c;那么就变成所有符合的内容都会被取代喔!

我们将这部份作个总结说明一下:

变量设置方式说明
${变量#关键字} ${变量##关键字}若变量内容从头开始的数据符合“关键字”&#xff0c;则将符合的最短数据 删除 若变量内容从头开始的数据符合“关键字”&#xff0c;则将符合的最 长数据删除
${变量%关键字} ${变量%%关键字}若变量内容从尾向前的数据符合“关键字”&#xff0c;则将符合的最短数据 删除 若变量内容从尾向前的数据符合“关键字”&#xff0c;则将符合的最 长数据删除
${变量/旧字串/新字串} ${变量//旧字串/新字串}若变量内容符合“旧字串”则“第一个旧字串会被新字串取代” 若变 量内容符合“旧字串”则“全部的旧字串会被新字串取代”
  • 变量的测试与内容替换

在某些时刻我们常常需要“判断”某个变量是否存在&#xff0c;若变量存在则使用既有的设置&#xff0c;若变量不 存在则给 一个常用的设置。

范例一:测试一下是否存在 username 这个变量&#xff0c;若不存在则给 username 内容为 root
[dmtsai&#64;study ~]$ echo ${username}<&#61;&#61;由于出现空白&#xff0c;所以 username 可能不存在&#xff0c;也可能是空字串
[dmtsai&#64;study ~]$ username&#61;${username-root}
[dmtsai&#64;study ~]$ echo ${username}
root <&#61;&#61;因为 username 没有设置&#xff0c;所以主动给 名为 root 的内容。
[dmtsai&#64;study ~]$ username&#61;"vbird tsai" <&#61;&#61;主动设置 username 的内容
[dmtsai&#64;study ~]$ username&#61;${username-root}
[dmtsai&#64;study ~]$ echo ${username}
vbird tsai <&#61;&#61;因为 username 已经设置了&#xff0c;所以使用旧有的设置而不以 root 取代

在上面的范例中&#xff0c;重点在于减号“ - ”后面接的关键字!基本上你可以这样理解:

new_var&#61;${old_var-content}新的变量&#xff0c;主要用来取代旧变量。新旧变量名称其实常常是一样的new_var&#61;${old_var-content}这是本范例中的关键字部分!必须要存在的哩!new_var&#61;${old_var-content}旧的变量&#xff0c;被测试的项目!new_var&#61;${old_var-content}变量的“内容”&#xff0c;在本范例中&#xff0c;这个部分是在“给 未设置变量的内容”

不过这还是有点问题!因为 username 可能已经被设置为“空字串”了!果真如此的话&#xff0c;那你还 可以使用下面的范例来给 username 的内容成为 root!

范例二:若 username 未设置或为空字串&#xff0c;则将 username 内容设置为 root
[dmtsai&#64;study ~]$ username&#61;${username-root}
[dmtsai&#64;study ~]$ echo ${username}<&#61;&#61;因为 username 被设置为空字串了!所以当然还是保留为空字串!
[dmtsai&#64;study ~]$ username&#61;${username:-root}
[dmtsai&#64;study ~]$ echo ${username}
root <&#61;&#61;加上“ : ”后若变量内容为空或者是未设置&#xff0c;都能够以后面的内容替换!

整理如下:

变量设置方式str 没有设置str 为空字串str 已设置非为空字串
var&#61;${str-expr}var&#61;exprvar&#61;var&#61;$str
var&#61;${str:-expr}var&#61;exprvar&#61;exprvar&#61;$str
var&#61;${str&#43;expr}var&#61;var&#61;exprvar&#61;expr
var&#61;${str:&#43;expr}var&#61;var&#61;var&#61;expr
var&#61;${str&#61;expr}str&#61;expr var&#61;exprstr 不变 var&#61;str 不变 var&#61;$str
var&#61;${str:&#61;expr}str&#61;expr var&#61;exprstr&#61;expr var&#61;exprstr 不变 var&#61;$str
var&#61;${str?expr}expr 输出至 stderrvar&#61;var&#61;$str
var&#61;${str:?expr}expr 输出至 stderrexpr 输出至 stderrvar&#61;$str

转:https://www.cnblogs.com/uetucci/p/7799855.html



推荐阅读
  • 基于PgpoolII的PostgreSQL集群安装与配置教程
    本文介绍了基于PgpoolII的PostgreSQL集群的安装与配置教程。Pgpool-II是一个位于PostgreSQL服务器和PostgreSQL数据库客户端之间的中间件,提供了连接池、复制、负载均衡、缓存、看门狗、限制链接等功能,可以用于搭建高可用的PostgreSQL集群。文章详细介绍了通过yum安装Pgpool-II的步骤,并提供了相关的官方参考地址。 ... [详细]
  • centos安装Mysql的方法及步骤详解
    本文介绍了centos安装Mysql的两种方式:rpm方式和绿色方式安装,详细介绍了安装所需的软件包以及安装过程中的注意事项,包括检查是否安装成功的方法。通过本文,读者可以了解到在centos系统上如何正确安装Mysql。 ... [详细]
  • 本文介绍了如何在Azure应用服务实例上获取.NetCore 3.0+的支持。作者分享了自己在将代码升级为使用.NET Core 3.0时遇到的问题,并提供了解决方法。文章还介绍了在部署过程中使用Kudu构建的方法,并指出了可能出现的错误。此外,还介绍了开发者应用服务计划和免费产品应用服务计划在不同地区的运行情况。最后,文章指出了当前的.NET SDK不支持目标为.NET Core 3.0的问题,并提供了解决方案。 ... [详细]
  • PG12新增的VACUUM命令的SKIP_LOCKED选项
    PG12版本的VACUUM命令新增了SKIP_LOCKED选项,该选项使得vacuum命令在遇到被lock住的table时可以跳过并被视为成功执行。之前的版本中,vacuum命令会一直处于等待状态。本文还提到了PostgreSQL 12.1版本的相关信息。 ... [详细]
  • Hadoop2.6.0 + 云centos +伪分布式只谈部署
    3.0.3玩不好,现将2.6.0tar.gz上传到usr,chmod-Rhadoop:hadophadoop-2.6.0,rm掉3.0.32.在etcp ... [详细]
  • quartus管脚分配后需要保存吗_嵌入式必须会的一些硬件面试题,要试一试吗?你过来呀!...
    1、下面是一些基本的数字电路知识问题,请简要回答之。(1)什么是Setup和Hold时间?答:SetupHoldTime用于测试芯片对输入 ... [详细]
  • 本文介绍了C#中生成随机数的三种方法,并分析了其中存在的问题。首先介绍了使用Random类生成随机数的默认方法,但在高并发情况下可能会出现重复的情况。接着通过循环生成了一系列随机数,进一步突显了这个问题。文章指出,随机数生成在任何编程语言中都是必备的功能,但Random类生成的随机数并不可靠。最后,提出了需要寻找其他可靠的随机数生成方法的建议。 ... [详细]
  • LVS实现负载均衡的原理LVS负载均衡负载均衡集群是LoadBalance集群。是一种将网络上的访问流量分布于各个节点,以降低服务器压力,更好的向客户端 ... [详细]
  • CentOS7.8下编译muduo库找不到Boost库报错的解决方法
    本文介绍了在CentOS7.8下编译muduo库时出现找不到Boost库报错的问题,并提供了解决方法。文章详细介绍了从Github上下载muduo和muduo-tutorial源代码的步骤,并指导如何编译muduo库。最后,作者提供了陈硕老师的Github链接和muduo库的简介。 ... [详细]
  • Python项目实战10.2:MySQL读写分离性能优化
    本文介绍了在Python项目实战中进行MySQL读写分离的性能优化,包括主从同步的配置和Django实现,以及在两台centos 7系统上安装和配置MySQL的步骤。同时还介绍了创建从数据库的用户和权限的方法。摘要长度为176字。 ... [详细]
  • 本文介绍在使用vmware中配置centos6.5时遇到的网络问题,包括host-only和natip的配置,以及无法上网的原因。同时提供了解决方法,包括去掉host-only配置文件中的gateway。 ... [详细]
  • LINUX学习之centos7营救模式
    今天卸载软件的时候,不小心把GNOME的一些组件给卸了,导致桌面无法正常开启,会卡在启动过程中,而我的开机启动模式又是设置为图形界面,所以一开LINUX就卡住了,进入不了命令行界面 ... [详细]
  • 花瓣|目标值_Compose 动画边学边做夏日彩虹
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了Compose动画边学边做-夏日彩虹相关的知识,希望对你有一定的参考价值。引言Comp ... [详细]
  • 今天就跟大家聊聊有关怎么在Android应用中实现一个换肤功能,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根 ... [详细]
  • SmartRefreshLayout自定义头部刷新和底部加载
    1.添加依赖implementation‘com.scwang.smartrefresh:SmartRefreshLayout:1.0.3’implementation‘com.s ... [详细]
author-avatar
兔牙的猪蹄
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有