Shell 的变量功能
创始人
2025-05-30 14:58:16
0

什么是变量??

应该很好理解吧,y=ax+b,y就是变量,ax+b就是变量的内容,等号左边是未知数,等号右边是已知数,简单来说,变量是一组文字或符号等,来替换一些设置或一串保留的数据。

变量的使用与设置 

变量的使用 :echo

可以利用echo这个命令来使用变量,在变量被使用时,前面必须加上美元符号【$】,或者以${变量}的方式表示。

那么如何设置或修改某个变量名称呢,使用=来连接变量和它的内容,在bash中,当一个变量名称未被设置时,默认的内容为空。 

变量设置的规则:

  • 变量与变量内容以一个等号(=)来连接
  • 等号两边不能有空格
  • 变量名称只能是英文字母或数字,但是开头字符不能是数字
  • 变量内容若有空格可以使用双引号(" ")或单引号(' ')将变量内容结合起来 (双引号内的特殊字符如 $ 等,可以保留其原本的特性,单引号内的特殊字符则仅为一般字符)
[root@linux ~]# var="lang is $LANG"
[root@linux ~]# echo ${var}
lang is zh_CN.UTF-8
[root@linux ~]# var='lang is $LANG'
[root@linux ~]# echo ${var}
lang is $LANG
  • 可用转义字符 \ 将特殊符号(如[Enter]、$、\、空格、'等)变成一般字符
[root@linux ~]# myname=li\ si
[root@linux ~]# echo ${myname}
li si
  • 在一串命令的执行中,还需要借助其他额外的命令所提供的信息时,可以使用但反引号【`命令`】或【$(命令)】
[root@linux ~]# version=$(uname -r)
[root@linux ~]# echo ${version}
3.10.0-1160.el7.x86_64
  • 若该变量为扩增变量内容时,则可用:"$变量名称" 或 ${变量}  累加内容
[root@linux ~]# echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
[root@linux ~]# PATH="$PATH":/home/bin
[root@linux ~]# echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin:/home/bin
  • 若该变量需要在其它子程序执行,则需以export来使变量变成环境变量
[root@linux ~]# name=yan
[root@linux ~]# bash #进入所谓的子进程
[root@linux ~]# echo ${name}[root@linux ~]# exit #离开这个子进程
exit
[root@linux ~]# export name #设置为环境变量
[root@linux ~]# bash #进入所谓的子进程
[root@linux ~]# echo ${name}
yan
  • 通常大写字符为系统默认变量,自行设置变量可以使用小写字符,方便判断
  • 取消变量的方法为unset
[root@linux ~]# echo ${name}
yan
[root@linux ~]# unset name
[root@linux ~]# echo ${name}

环境变量的功能

环境变量可以实现根目录(主文件夹)的变换、提示字符的显示、执行文件查找的路径等。目前shell环境中可用env和export两个命令来查看默认环境变量的多少。

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

  • 用set观察所有变量(含环境变量与自定义变量)
[root@linux ~]# set
BASH=/usr/bin/bash
BASH_VERSINFO=([0]="4" [1]="2" [2]="46" [3]="2" [4]="release" [5]="x86_64-redhat-linux-gnu")
BASH_VERSION='4.2.46(2)-release'
COLUMNS=157
HISTFILE=/root/.bash_history
HISTFILESIZE=1000
IFS=$' \t\n'
LANG=zh_CN.UTF-8
MACHTYPE=x86_64-redhat-linux-gnu
OSTYPE=linux-gnu
PS1='[\u@\h \W]\$ '
PS2='> '
PS4='+ '
···
# 还有好多库函数功能

基本上,在Linux默认的情况中,使用{大写的字母}来设置的变量一般为系统内定需要的变量。

PS1:(提示字符的设置)

 

这个就是命令提示字符,每次按下[Enter]按键去执行某个命令后,最后要再次出现提示字符时,就会主动去读取这个变量值,上面的PS1内显示的是一些特殊符号,这些特殊符号可以显示不同的信息,每个Linux发行版的bash默认的PS1变量内容可能有些许差异,下面为一些符号的意义:

  • \d:可显示出【星期 月 日】的日期格式,如:【Mon Jan 1】
  • \H:完整的主机名
  • \h:仅取主机名在第一个小数点之前的名字
  • \t:显示时间,为24小时格式的【HH:MM:SS】
  • \T:显示时间,为12小时格式的【HH:MM:SS】
  • \A:显示时间,为24小时格式的【HH:MM】
  • \@:显示时间,为12小时格式的【am/pm】样式
  • \u:目前用户的账号名称
  • \v:BASH的版本信息
  • \w:完整的工作目录名称,由根目录写起的目录名称,但根目录会以~替换
  • \W:利用basename函数取得工作目录名称,所以仅会列出最后一个目录名
  • \#:执行的第几个命令
  • \$:提示字符,如果是root时,提示字符为#,否则就是$

$:(关于本shell的PID)

表示目前这个shell的进程号

: (关于上个执行命令的返回值)

当我们执行某些命令时,这些命令都会返回一个执行后的代码,一般来说,如果成功执行该命令,则会返回一个0值,如果执行过程发生错误,就会返回一个错误代码,一般以非0的数值来替换

  • export:自定义变量转成环境变量

和env这两者差异在于该变量是否会被子进程所继续引用

当登入linux并取得一个bash之后,你的bash就是一个独立的进程,这个进程的识别使用的是进程标识符,也就是PID,接下来在这个bash下面所执行的任何命令都是由这个bash所衍生出来的,那些被执行的命令就被称为子进程。

子进程仅会继承父进程的环境变量,不会继承父进程的自定义变量。

所以,我们可以让自定义变量变为环境变量,不就可以该变量值继续存在与子进程了

[root@linux ~]# export 变量名称

如果仅执行export而没有接变量时,那么此时会把所有的环境变量显示出来 

[root@linux ~]#export
declare -x HISTCONTROL="ignoredups"
declare -x HISTSIZE="1000"
declare -x HOME="/root"
declare -x HOSTNAME="linux"
declare -x LANG="zh_CN.UTF-8"
declare -x LESSOPEN="||/usr/bin/lesspipe.sh %s"
declare -x LOGNAME="root"
declare -x LS_COLORS="rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=01;05;37;41:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arc=01;31:*.arj=01;31:*.taz=01;31:*.lha=01;31:*.lz4=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.tzo=01;31:*.t7z=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.dz=01;31:*.gz=01;31:*.lrz=01;31:*.lz=01;31:*.lzo=01;31:*.xz=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.alz=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.cab=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.axv=01;35:*.anx=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=01;36:*.au=01;36:*.flac=01;36:*.mid=01;36:*.midi=01;36:*.mka=01;36:*.mp3=01;36:*.mpc=01;36:*.ogg=01;36:*.ra=01;36:*.wav=01;36:*.axa=01;36:*.oga=01;36:*.spx=01;36:*.xspf=01;36:"
declare -x MAIL="/var/spool/mail/root"
declare -x OLDPWD
declare -x PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin:/home/bin"
declare -x PWD="/root"
declare -x SELINUX_LEVEL_REQUESTED=""
declare -x SELINUX_ROLE_REQUESTED=""
declare -x SELINUX_USE_CURRENT_RANGE=""
declare -x SHELL="/bin/bash"
declare -x SHLVL="2"
declare -x SSH_CLIENT="192.168.134.1 55868 22"
declare -x SSH_CONNECTION="192.168.134.1 55868 192.168.134.140 22"
declare -x SSH_TTY="/dev/pts/0"
declare -x TERM="xterm"
declare -x USER="root"
declare -x XDG_DATA_DIRS="/root/.local/share/flatpak/exports/share:/var/lib/flatpak/exports/share:/usr/local/share:/usr/share"
declare -x XDG_RUNTIME_DIR="/run/user/0"
declare -x XDG_SESSION_ID="1"

影响显示结果的语系变量

linux支持多少种语系可由locale命令来查询

[root@linux ~]#locale -a
# 前面还有好多···
zh_CN
zh_CN.gb18030
zh_CN.gb2312
zh_CN.gbk
zh_CN.utf8
zh_HK
zh_HK.big5hkscs
zh_HK.utf8
zh_SG
zh_SG.gb2312
zh_SG.gbk
zh_SG.utf8
zh_TW
zh_TW.big5
zh_TW.euctw
zh_TW.utf8
zu_ZA
zu_ZA.iso88591
zu_ZA.utf8

繁体中文语系至少支持了两种以上的编码,一种是Big5,另一种是UTF-8编码

可以逐一设置每个与语系有关的变量数据,但是,如果其他的语系变量都未设置,且有设置LANG或是LC_ALL时,则其他的语系变量就会被这两个变量所替换。

当然可以让每个用户自己去调整自己喜好的语系,整体系统默认的语系定义在 /etc/locale.conf里面 

[root@linux ~]#cat /etc/locale.conf
LANG="zh_CN.UTF-8"

变量键盘读取、数组与声明

  • read:读取来自键盘输入的变量

语法:#read [-pt] 变量

-p:后面可接提示字符

-t:后面可接等待的秒数

  • declare,typeset:声明变量类型

declare和typeset功能一样,如果使用declare后面不接任何参数,那么bash就会主动的将所有的变量名称与内容全部显示出来。

语法:#declare [-airx] 变量

-a:将变量定义为数组类型

-i:将变量定义为整形

-r:将变量设置为readonly类型,该变量不可更改,也不能unset(如果真不小心将变量设置为这个类型,通常要注销再登录才能恢复该变量的类型)

-x:将变量定义为环境变量

在默认的情况下,bash对于变量由几个基本的定义:

  1. 变量类型默认为字符串
[root@linux ~]#sum=1+2+3
[root@linux ~]#echo ${sum}
1+2+3
[root@linux ~]#declare -i sum=1+2+3
[root@linux ~]#echo ${sum}
6
  1. bash环境中的数值运算,默认最多仅能达到整数形态 
[root@linux ~]#declare -x sum
[root@linux ~]#export | grep sum
declare -ix sum="6"
[root@linux ~]#declare -r sum  # 改不了了
[root@linux ~]#sum=1
bash: sum: 只读变量
[root@linux ~]#declare +x sum
[root@linux ~]#export | grep sum
[root@linux ~]#declare -p sum  # -p可以单独列出变量的类型
declare -ir sum="6"
  • 数组(array)变量类型

 数组的设置方式:var[index]=content;目前bash提供的是一维数组

[root@linux ~]#var[0]=1
[root@linux ~]#var[1]=2
[root@linux ~]#var[2]=3
[root@linux ~]#echo "${var[0]},${var[1]},${var[2]}"
1,2,3

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

bash可以限制用户的某些系统资源, 包括可以开启的文件数量,可以使用的CPU时间,可以使用的内存总量等,可用ulimit设置

语法:ulimit [-SHacdfltu] [配额]

-H:严格的设置,必定不能超过这个设置的数值

-S:警告的设置,可以超过这个设置值,但是超过后会有警告信息

-a:后面不接任何选项和参数,可列出所有的限制额度

-c:当某些程序发生错误时,系统可能会将该程序在内存中的信息写成文件,这种文件被称为内核文件。此为限制每个内核文件的最大容量

-d:程序可使用的最大段内存容量

-f:此shell可建立的最大文件容量(一般可设置为2GB)单位为Kbytes

-l:可用于锁定的内存量

-t:可使用的最大CPU时间(单位为秒)

-u:单一使用者可以使用的最大进程数量

 

例:限制使用者仅能建立10MBytes一下容量的文件

[root@linux ~]# ulimit -f 10240
[root@linux ~]# ulimit -a | grep 'file size'
core file size          (blocks, -c) 0
file size               (blocks, -f) 10240
[root@linux ~]# dd if=/dev/zero of=123 bs=1M count=20
文件大小超出限制(吐核)
[root@linux ~]# rm 123

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

语法:

${变量#关键词}若变量内容从头开始的数据符合关键词,则将符合的最短数据删除
${变量##关键词}若变量内容从头开始的数据符合关键词,则将符合的最长数据删除
${变量%关键词}若变量内容从尾向前的数据符合关键词,则将符合的最短数据删除
${变量%%关键词}若变量内容从尾向前的数据符合关键词,则将符合的最长数据删除
${变量/旧字符串/新字符串}若变量内容符合旧字符串,则第一个字符串会被新字符串替换
${变量//旧字符串/新字符串}若变量内容符合旧字符串,则全部的字符串会被新字符串替换
[root@linux ~]# path=${PATH}
[root@linux ~]# echo ${path}
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
[root@linux ~]# echo ${path#/*:}
/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
[root@linux ~]# echo ${path##/*:}
/root/bin[root@linux ~]# echo ${path%:*bin}
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin
[root@linux ~]# echo ${path%%:*bin}
/usr/local/sbin[root@linux ~]# echo ${path/sbin/SBIN}
/usr/local/SBIN:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
[root@linux ~]# echo ${path//sbin/SBIN}
/usr/local/SBIN:/usr/local/bin:/usr/SBIN:/usr/bin:/root/bin

在某些时刻常常需要判断某个变量是否存在,若存在则使用已有的设置,若不存在则给一个常用的设置。

str没有设置str为空字符串str已设置非为空字符串
var=${str-expr}var=exprvar= var=$str
var=${str:-expr}var=exprvar=exprvar=$str
var=${str+expr}var= var=exprvar=expr
var=${str:+expr}var= var= var=expr
var=${str=expr}

str=expr

var=expr

str 不变

var= 

str 不变

var=$str

var=${str:=expr}

str=expr

var=expr

str=expr

var=expr

str 不变

var=$str

var=${str?expr}expr 输出至 stderrvar=var=$str
var=${str:?expr}expr 输出至 stderrexpr 输出至 stderrvar=$str

相关内容

热门资讯

走进小城看消费丨江西资溪:低碳...   夏日时节下午4点,江西省抚州市资溪县大觉山景区漂流终点依然热闹。来自南昌的游客余鑫漂流结束后没有...
【中原晨会0625】市场分析专... 来源:市场资讯 (来源:中原证券研究所) 本期重点研报目录 【中原策略】市场分析:电子半导体领涨 ...
南向资金连买4日!低费率+可月... 6月25日早盘,港股红利资产震荡整理。截至11时14分,港股红利低波ETF招商(520550)下跌0...
618成交破百万!紫荆花用一套... 一年一度的618年中大促,是消费市场的晴雨表,也是品牌间最激烈的角力场。当各大品牌在直播间里铆足了劲...
原创 黄... 2026年6月25日的国际金价已经从前期的5500美元高点跌到4200美元下方,累计跌幅超过22%,...
英伟达CEO:Vera Rub... 截至9:38,中证半导体材料设备主题指数(931743)涨2.36%创新高;权重股中,中微公司涨3....
再被催债16亿!“钢铁大王”戴... 澎湃新闻记者 贺梨萍 因“铁本事件”入狱五年的戴国芳重返钢铁行业,但他并没有完成从阶下囚再到“钢铁大...
周三原油价格下跌 随着美国和伊朗在和平谈判中取得进展,越来越多的油轮公开穿越霍尔木兹海峡,原油在战时的价格上涨已经蒸发...
这种蛋白是大脑衰老的开关 这种蛋白是大脑衰老的开关 清晨,假设一位五十岁左右的王女士发现自己常常把手机放在熟悉的抽屉里又找不到...
信通院牵头算力Token出海生... 盘面上,截至11:04,中证科创创业50指数(931643)涨1.68%,创历史新高;权重股中,芯原...
海外 774 亿营收背后:日本... 文 | 游戏价值论 6月23日,彭博社报道了腾讯正在围绕出售多家日本游戏工作室少数股权开展谈判,包...
餐饮“抢人”大战:把店开到公交... 作者 |餐饮老板内参 内参君 医院、公交站、演唱会…餐饮品牌,正在无孔不入 在北京儿童医院,肯德基...
快讯 | 外资扫货!陈翊庭:港... 港交所行政总裁陈翊庭在接受《中国证券报》专访时指出,国际资本对中国资产的看法已彻底扭转,布局中国市场...
2777.77元!A股“股王”... 25日早盘,昨天创下历史新高的A股“股王”联讯仪器,今天上午继续走强,盘中股价再度刷新历史新高。 截...
原创 今... 欧洲自己的媒体直接下结论,欧盟衰退躲不掉,内部分裂拦不住,现在就连欧洲顶尖工业巨头,都偷偷在用中国的...
黄仁勋股东大会放言:本轮AI基... 在当地时间6月24日的英伟达(NVDA.O)2026年度股东大会上,股东批准了该公司全部10名董事会...
国际油价大跌 新华社消息, 纽约原油期货主力合约价格24日盘中跌破每桶70美元,为伊朗战事爆发以来首次。 市场分析...
马云带队插秧,什么信号? 一场别开生面的“务农”,让外界看到了一个不一样的阿里巴巴。 近日,阿里巴巴合伙人、高德董事长刘振飞在...
全球最大产能,最高丰度达99.... 本文转自【科技日报】; 6月23日,高丰度硼-10同位素技术暨产业化成果发布会在山东省东营市举办,全...
黄金大跳水!金饰克价年内暴跌近... 25日,现货黄金盘中震荡,截至发稿,报3985.070美元/盎司,跌0.17%。 当地时间24日,...