程序锅

  • 首页
  • 分类
  • 标签
  • 归档
  • 关于

  • 搜索
基础知识 Etcd LeetCode 计算机体系结构 Kubernetes Containerd Docker 容器 云原生 Serverless 项目开发维护 ELF 深入理解程序 Tmux Vim Linux Kernel Linux numpy matplotlib 机器学习 MQTT 网络基础 Thrift RPC OS 操作系统 Clang 研途 数据结构和算法 Java 编程语言 Golang Python 个人网站搭建 Nginx 计算机通用技术 Git

Linux Cheat Sheet - Bash 变量的全面整理

发表于 2020-12-30 | 分类于 Linux | 0 | 阅读次数 3748

变量的取用

变量在取用时,前面需要加上钱字号 “$”。

echo $variable

echo ${variable}

echo $PATH

echo ${PATH}

变量的设置与修改

myname=Dawn	# 设置变量 myname 的内容为 Dawn
echo ${myname}

unset	myname # 取消 myname 的设置

bash 中假如 echo 一个没有设置内容的变量时,它会显示空的值。但是在某些 shell 中,去 echo 这种变量可能会出现错误。

变量的设置与修改需要注意以下几点:

  • 变量名称只能是英文、字母、数字,开头不能是数字。

  • 等号两边不能直接接空白字符,如 myname = VBird。

  • 变量内容若有空白字符可使用双引号 "",或单引号 '' 将变量内容结合起来。

    • 双引号内的特殊字符如 $ 等将会保有原本的特性,如 var="lang is $LANG" ,echo 则会得到 lang is en_US.UTF-8。
    • 单引号的特殊字符就会被当成一般字符。
  • 可使用 \ 将特殊符号([Enter]、$、\、单引号、双引号、反单引号)转换为一般字符。

  • 在一串指令中,还需要借由其他额外的指令所提供的的信息时,可以使用反单引号或者 $。比如 version=$(uname -r),那么 echo $version 的时候就会得到 20.1.0。

    # 进入当前 kernel 的模块目录
    cd /lib/modules/`uname -r`/kenrel
    cd /lib/modules/$(uname -r)/kernel	# 这种方式更好
    
    # 上述这种方式其实作了两次动作
    # - 先进行反单引号内的动作,得到结果
    # - 再将结果带入原指令
    
  • 若要为变量扩展内容时,则可用 $变量名称或${变量}累加内容,如 PATH=${PATH}:/home/bin 。

  • 通常大写字符为系统默认变量或者环境变量,自行设置变量可以使用小写字符,方便判断。一般来说,不论是否是环境变量,只要跟正在使用的 shell 的操作接口有关的变量都会被设置为大写字符。

当你有一个常去的工作目录,比如 /home/dawnguo/workspace,怎么使得 cd 到这个目录的动作简化呢?我们可以设置一个变量 work=/home/dawnguo/workspace(这个变量可以在 bash 的配置文件 .bashrc 中直接指定),接下去使用 cd $work 就好了。

变量的有效范围

Bash 中的变量也有范围,默认情况下用户在一个 shell 中定义的变量是不会传到子进程中去的。若希望该变量在其他子进程也可以执行,那么则需要 export 来使变量变成环境变量,如 export PATH。目前这个 shell 的情况下,去启用一个新的 shell 时,新的 shell 就是子进程。假如没有使用 export,那么父进程的自定义变量是无法在子进程中使用的。但是使用 export 将其变为环境变量之后就可以在子进程中使用了。

变量从键盘读取

要想读取来自键盘输入的变量,就需要 read 这个指令。

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

-p:后面可以接提示字符!
-t:后面可以接等待的“秒数!”这个比较有趣~不会一直等待使用者啦!

# 将键盘输入的内容作为 demo 这个变量的内容
$ read demo

# 30s 之内输入,如果 30s 之内没有任何输入,那么会自动略过。假如 30s 之内有输入,那么输入的内容将会作为变量 named 的内容。
$ read -p "Please enter your name: " -t 30 named

声明变量

变量类型默认为“字符串”,假如想要声明变量为其他类型,需要使用 declare 或者 typeset(两个是一样的功能)。如果 declare 后面没有接任何参数,那么 bash 就会将所有的变量名称和内容通通列出来,就好像 set 一样。

declare [-aixr] variable

-a :将后面名为 variable 的变量定义成为阵列 (array) 类型
-i :将后面名为 variable 的变量定义成为整数数字 (integer) 类型
-x :用法与 export 一样,就是将后面的 variable 变成环境变量;
-r :将变量设置成为 readonly 类型,该变量不可被更改内容,也不能 unset,只能退出登陆才能恢复哦
-p :可以单独列出变量的类型
+x :将 - 变成 + 可以取消 x 动作

# echo 的话会显示设置的内容,而不会进行相加
$ sum=100+30+50

# 这种情况下会进行相加
$ declare -i sum=100+30+50

需要注意的是 bash 中的数值运算,默认最多仅能到达整数形态,所以 1/3 结果为 0。

array 变量类型

在 bash 里面设置 array 类型的变量(目前 bash 提供的只有一维阵列),如下所示。

$ declare -a var[index]=content
$ var[1]="small min"
$ var[2]="big min"
$ var[3]="nice min"
$ echo ${var[1]}

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

变量除了可以直接设置来修改原来的内容之外,还可以对变量的内容进行删除、取代与替换。

变量内容的删除与取代

# 格式是:{variable#/*local/bin:}
# - variable 就是变量的名称,比如上面的 path
# - # 表示从变量内容的最前面开始往右删除,但是仅删除最短匹配的那个
# - ## 表示从变量内容的最前面开始往右删除,但是删除的是最长匹配的那个
# - /*local/bin: 相当于匹配模式,用于匹配符合模式的字符串

$ path=${PATH}
$ echo $path
/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin 

# 删除从左到第一个 local/bin 的路径
$ echo ${path#/*local/bin:}
/usr/bin:/bin:/usr/sbin:/sbin

# 删除第一个匹配 /*: 的内容,即删除第一个路径
$ echo ${path#/*:}
/usr/bin:/bin:/usr/sbin:/sbin

# 删除前面所有的路径,仅保留最后一个目录
$ echo ${path##/*:}
/sbin

# % 从右往左开始删除内容,最后一个假如含 bin 的话,则删除最后一个目录
$ echo ${path%:*bin}
/usr/local/bin:/usr/bin:/bin:/usr/sbin

# %% 则是最长匹配,删除只剩一个目录了
$ echo ${path%%:*bin}
/usr/local/bin

# 将 path 变量内容内的 sbin 替换为 SBIN
$ echo ${path/sbin/SBIN}
/usr/local/bin:/usr/bin:/bin:/usr/SBIN:/sbin

# 如果是两条斜线,那么所有符合的内容都会被替换
$ echo ${path//sbin/SBIN}
/usr/local/bin:/usr/bin:/bin:/usr/SBIN:/SBIN

更加完整的设置方式如下所示:

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

变量的测试与内容替换

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

# username 假如没有设置的话,那么 username 被设置为 root
$ username=${username-root}
$ echo ${username}
root
$ username=dawn
$ username=${username-root}
$ echo ${username}
dawn

# 格式如下:new_var=${old_var-content}
# - new_var 是新的变量用来替换 old_var。new_var 和 old_var 常常是一样的
# - content 假如 old_var 没有被设置的话,那么则设置为 content 的内容

# 假如 username 没有被设置或者设置为空串,那么 username 则被设置为 root
$ username=${username:-root}
$ echo ${username}
root

# 假如 str 不存在,那么 str 和 var 的内容都将被设置为 newvar
$ unset str; var=${str=newvar}
$ echo "var=${var} str=${str}"
var=newvar str=newvar

# 假如 str 存在,那么 str 和 var 的内容都将被设置为 oldvar
$ str="oldvar"; var=${str=newvar}
bash-3.2$ echo "var=${var} str=${str}"
var=oldvar str=oldvar

# 假如 str 不存在,那么 var 的测试结果直接显示 “novar”
$ unset str; var=${str?novar}
bash: str: novar

# 假如 str 存在,那么 var 的内容与 str 的内容一样
$ str="oldvar"; var=${str?novar}
$ echo "var=${var} str=${str}"
var=oldvar str=oldvar

更加完整的替换表格如下,一般来说,str 表示仅为“没有该变量”,str: 表示 str 没有设置或者设置成了空串。

变量设置方式str 没有设置str 为空字串str 已设置非为空字串
var=$var=exprvar=var=$str
var=$var=exprvar=exprvar=$str
var=${str+expr}var=var=exprvar=expr
var=${str:+expr}var=var=var=expr
var=$str=expr var=exprstr 不变 var=str 不变 var=$str
var=$str=expr var=exprstr=expr var=exprstr 不变 var=$str
var=${str?expr}expr 输出至 stderrvar=var=$str
var=${str:?expr}expr 输出至 stderrexpr 输出至 stderrvar=$str

环境变量

常用命令

  • env 查看环境变量与常见环境变量说明。env 是 environment 的简写,会列出来所有的环境变量。

  • set 查看所有变量(含环境变量与自定义变量)。set 除了将环境变量显示出来之外,还会将 bash 中的其他变量都显示出来。

  • export 将自定义变量(局部变量)转成环境变量(全局变量)。自定义变量和环境变量的区别在于该变量能否被子进程所继续使用,子进程仅会继续父进程的环境变量,不会进程父进程的自定义变量。export 后面没有接要导出的变量时,那么会把所有的环境变量显示出来。

    在理论上为什么环境变量的数据可以被子进程所引用呢?这是因为内存配置的关系:

    • 当启动一个 shell 之后,操作系统会分配一内存区域给 shell 使用,此内存中的变量可以给子进程使用;
    • 若在父进程中使用 export ,那么可以让自定义变量的内容写到上述的内存区域中(环境变量);
    • 当启动一个新的 shell 时,子 shell 可以将父 shell 环境变量所在的内存区域导入自己的环境变量区域中。

    这个环境变量跟 bash 的操作环境有点不大一样,PS1 并不是环境变量,但是会影响到 bash 的提示字符。

常见系统变量

  • HOME 代表使用者的主目录。

  • SHELL 表示目前这个环境使用的是哪个 SHELL。

  • HISTSIZE 表示历史命令的数量。

  • PATH 就是可执行文件搜索的路径啦,目录和目录中间以冒号(:)分隔,由于文件的搜索依序由 PATH 的变量内的目录来查询,所以目录的顺序也是很重要的。

    当下达 ls 这个指令时,系统就是通过 PATH 这个变量里面的内容所记录的路径顺序来寻找指令的呢!如果在搜索完 PATH 变量内的路径还找不到 ls 这个指令时,就会在屏幕上显示 “command not found” 的错误讯息。

  • LANG 是语系数据的变量,也就是编码相关的变量。Linux 到底支持多少语系,我们可以使用 locale -a 这个指令来进行查询。而查看当前除 LANG 这个变量之外,其他跟语系相关的变量可以使用 locale 这个指令(不加任何参数)查询得到。

    $ locale
    LANG="zh_CN.UTF-8"
    LC_COLLATE="zh_CN.UTF-8"
    LC_CTYPE="zh_CN.UTF-8"
    LC_MESSAGES="zh_CN.UTF-8"
    LC_MONETARY="zh_CN.UTF-8"
    LC_NUMERIC="zh_CN.UTF-8"
    LC_TIME="zh_CN.UTF-8"
    LC_ALL=
    

    上面这些变量都是跟语系相关的,假如其他变量你都未设置,仅仅设置了 LANG 或者 LC_ALL 这两个变量,那么其他的变量都会被这两个变量所取代。这也是为啥在 Linux 中仅设置 LANG 和 LC_ALL 这两个变量就可以了。

    有时候 Linux 主机的终端机接口(tty1 ~tty6)的环境下,虽然设置了中文的语系,但是还是会有一堆乱码。这是因为终端机接口环境下无法显示像中文这么复杂的编码文字,所以会产生乱码。这个时候就需要在 tty1~tty6 的环境下加装一些中文化接口的软件,才能看到中文。此时,通过 ssh 的方式可能会看到中文,因为 ssh 的终端软件支持中文。

  • RANDOM 是随机数的变量了,目前大多数的 distributions 都会有乱数产生器,就是 /dev/random 这个文件。可以通过这个乱数文件相关的变量 $RANDOM 来随机取得数据,这个值介于 0~32767。

    假如想要取得 0~9 之间的数值的话,那么可以如下所示:

    declare -i number=$RANDOM*10/32768; echo $number
    
  • MAIL 当使用 mail 这个指令收信时,系统会读取的邮件信箱文件。

其他常用变量

  • PS1 提示字符的设置,也就是输入命令前面的提示内容,比如 root@pc~。每次按下 [Enter] 按键去执行某条指令后,最后需要再出现提示字符的时候就会主动读取这个变量值了。PS1 中设置的内容是一些特殊符号,这些符号会显示不同信息,如下所示,更详细的可以使用 man bash 。

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

    假如要设置成下面这样的效果,其中 12 表示第 12 条指令,那么 PS1 可以如下这样设置

    PS1='[\u@\h \w \A #\#]\$ '
    
  • $,当前 shell 的 PID。

    echo $$
    
  • ? 上一条执行的指令的回传值。当我们执行某些指令时,这些指令都会回传一个执行后的代码,一般来说,如果成功地执行了指令,则会回传一个 0 值;执行过程发生了错误,那么会回传“错误代码”。

  • OSTYPE, HOSTTYPE, MACHTYPE,主机硬件与 kernel 的等级。比如 linux-gnu、x86-64。

卷死我
dawnguo 微信支付

微信支付

dawnguo 支付宝

支付宝

  • 本文作者: dawnguo
  • 本文链接: /archives/103
  • 版权声明: 本博客所有文章除特别声明外,均采用CC BY-NC-SA 3.0 许可协议。转载请注明出处!
# Linux
Ubuntu 16.04 的配置【摘记】
Linux Cheat Sheet - Bash 概念、配置、操作环境和常用命令
  • 文章目录
  • 站点概览
dawnguo

dawnguo

215 日志
24 分类
37 标签
RSS
Creative Commons
© 2018 — 2025 程序锅
0%