Shell 的变量功能
创始人
2025-05-30 15:50:47
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

相关内容

热门资讯

AWSECS:访问外部网络时出... 如果您在AWS ECS中部署了应用程序,并且该应用程序需要访问外部网络,但是无法正常访问,可能是因为...
AWSElasticBeans... 在Dockerfile中手动配置nginx反向代理。例如,在Dockerfile中添加以下代码:FR...
银河麒麟V10SP1高级服务器... 银河麒麟高级服务器操作系统简介: 银河麒麟高级服务器操作系统V10是针对企业级关键业务...
北信源内网安全管理卸载 北信源内网安全管理是一款网络安全管理软件,主要用于保护内网安全。在日常使用过程中,卸载该软件是一种常...
AWR报告解读 WORKLOAD REPOSITORY PDB report (PDB snapshots) AW...
AWS管理控制台菜单和权限 要在AWS管理控制台中创建菜单和权限,您可以使用AWS Identity and Access Ma...
​ToDesk 远程工具安装及... 目录 前言 ToDesk 优势 ToDesk 下载安装 ToDesk 功能展示 文件传输 设备链接 ...
群晖外网访问终极解决方法:IP... 写在前面的话 受够了群晖的quickconnet的小水管了,急需一个新的解决方法&#x...
不能访问光猫的的管理页面 光猫是现代家庭宽带网络的重要组成部分,它可以提供高速稳定的网络连接。但是,有时候我们会遇到不能访问光...
Azure构建流程(Power... 这可能是由于配置错误导致的问题。请检查构建流程任务中的“发布构建制品”步骤,确保正确配置了“Arti...