在各种Shell环境中都会用到变量的概念。Shell变量用来存放系统和用户需要使用的特定参数值,通过使用变量,Shell程序能够提供更加灵活的功能,适应性强。

常见的Shell变量的类型包括 系统变量位置变量预定义变量自定义变量

下面围绕这四种变量类型来举例

系统变量

Linux中的环境变量是由系统定义的一些变量,主要用于设置用户的工作环境,包括宿主目录、命令查找路径、用户当前目录、登录终端等。环境变量的值由linux系统自动维护,会随着用户状态的改变而改变。

env命令可以用来查看当前用户当前工作环境下的环境变量,可以试着用来查看一下,以下举出部分例子:

系统变量 变量含义
$SHELL 默认的 Shell 环境
$HOME 当前用户宿主目录
$IFS 内容字段分隔符,默认是空格
$LANG 默认系统语言
$PWD 当前所在目录
$UID 当前用户ID
$USER 当前用户
$HISTSIZE 历史命令大小
$RANDOM 随机生成一个0~32767的整数
$HOSTNAME 主机名
$PATH 默认系统寻找的可执行命令路径

位置变量

位置变量也称为位置参数,使用$1 $2 $3 ...,以执行命令为参照,从左到右的参数从$1依次类推。如:ls -lh /root,以ls为参照,-lh$1/root$2,需要注意的是从第10个开始要用花括号调用,例如${10}。命令或者脚本本身用$0表示,但$0属于预定义变量,而不是位置变量。

例:

# 脚本示例
$ vi result.sh
#!/bin/bash
SUM=`expr $1 + $2`
echo "$1 + $2 = $SUM"
# 脚本赋权
$ chmod +x result.sh
# 执行脚本
$ ./result.sh 3 4
3 + 4 = 7
# 执行脚本过程中3为$1,4为$2

shift 命令可对位置变量进行控制,命令没执行一次,变量的个数会减 1,本身有 $1$2 两个位置变量的情况下,执行一次 shift 后, $2 的值就变成了 $1 。如下所示

$ vim shift.sh
#!/bin/bash
echo "第一个参数为 $1"
echo "第二个参数为 $2"
echo "第三个参数为 $3"

echo "第一个参数为 $1"
shift
echo "第一个参数为 $1"
shift
echo "第一个参数为 $1"

$ sh shift.sh a b c
第一个参数为 a
第二个参数为 b
第三个参数为 c
第一个参数为 a
第一个参数为 b
第一个参数为 c

以上的例子可以看出,第一次输出abc时,$1=a,$2=b,$3=c,第二次输出abc时,$1=a,$1=b,$1=c,第二次输出完$1=a时,执行了一次 shift,在输出$1,已经变成了b。说明在执行 shift 后,执行脚本变成了 shift.sh b c,此时$1=b,以此类推,第二次执行 shift 后变成了 shift.sh c,此时$1=c。

以上总结,shift 用来依次删除从左到右的位置变量

上面例子使用的 shift,默认为 shift 1,1也可以是其它整数,就变成了删除从左到右 n 个位置变量

预定义变量

预定义变量是由Bash程序预先定义好的一类特殊变量,用户只能使用预定义变量,而不能创建新的预定义变量,也不能为预定义变量赋值。

比较常用的如下:

$# 表示命令行中位置参数的个数
$* 表示所有位置参数的内容
$@ 每个位置参数被看作独立的字符串
$? 表示前一条命令执行后的状态,返回值为0表示执行正确,任何非0值均表示执行出现异常
$0 表示当前执行的脚本或程序的名称。
$$ 当前进程PID
$! 上一条运行后台进程的PID

例:

# 编写脚本
$ vi predefine.sh
#!/bin/bash
echo "该脚本为 $0 "
echo "该脚本一共使用了 $# 个参数"
echo "参数分别为 $* "
# 脚本授权
$ chmod +x predefine.sh 
# 执行脚本
$ ./predefine.sh FeiYi \'s Blog
该脚本为 ./predefine.sh 
该脚本一共使用了 3 个参数
参数分别为 FeiYi 's Blog

自定义变量

自定义变量是由系统用户自己定义的变量,只有用户在自己的Shell环境中有效,因此又称为本地变量。在编写Shell脚本程序时,通常会设置一些特定的自定义变量,以适应程序执行过程中的各种变量,满足不同的需求。

定义变量

Bash中的变量定义相对C、C++、Java等语言还是比较简单的,只需要使用等号即可进行变量的定义。

格式为:变量名=变量值

等号两边不能有空格。变量名须以字母或者下划线开头,名称中不能包含特殊字符(+、-、*、/、.、?、%、&、#等)。

例如要定义一个变量名为CYJ,值为FeiYi,一个变量名为PJF,值为Blog

CYJ=FeiYi
PJF=Blog

查看和引用变量的值

通过在变量名前加“$”符号,可以引用变量的值。使用echo命令可以查看变量,可以在一条echo命令中同时查看多个变量值。

$ echo $CYJ $PJF
FeiYi Blog

当变量名容易和紧跟其后的字符相混淆时,需要添加大括号{}将变量名扩起来,否则将无法正确解析该变量的值,对于定义的变量显示空值。

$ echo $CYJBlog   //变量值CYJBlog未定义

$ echo ${CYJ}Blog
FeiYiBlog

变量赋值的特殊操作

双引号(” “)

双引号主要起界定字符串的作用,特别是当复制的内容中包含空格时,必须以双引号引起来;其他情况双引号可以省略

$ MU=FeiYi Blog
bash: Blog: 未找到命令...
$ MU="FeiYi Blog"
$ echo $MU
FeiYi Blog

在双引号的范围内,使用$符号也可以引用其他变量的值,从而能够直接调用现有变量的值来赋给新的变量

$ MU="FeiYi $PJF"
$ echo $MU
FeiYi Blog

单引号(’ ‘)

当要赋值的内容中包含$、”、\等具有特殊含义的字符时,应该使用单引号引起来。在单引号范围内无法引用其他的变量值,任何字符都将看做普通字符。但赋值内容中包含单引号时,需要使用\进行转义,避免冲突

$ MU='FeiYi $PJF'
$ echo $MU
FeiYi $PJF

反撇号(``)

反撇号主要用于命令替换,允许将执行某个命令的屏幕输出结果赋值给变量。反撇号括起来的范围必须是能够执行的命令,否则将会出错。

$ ls -lh `which useradd`
-rwxr-x---. 1 root root 116K 11月  6 2016 /usr/sbin/useradd

这相当于执行了两条命令,先通过 which useradd 找到 useradd 命令所在的路径,在通过 ls -lh 查看该命令文件的详细信息

需要注意的是,使用反撇号难以在一行命令中实现嵌套命令替换操作,这时可以改用“$( )”来代替反撇号操作。

$ rpm -qc `rpm -qf `which useradd``
rpm:未给出要查询的参数
未安装软件包 useradd 

$ rpm -qc $(rpm -qf `which useradd`)
/etc/default/useradd
/etc/login.defs

$ rpm -qc $(rpm -qf $(which useradd))
/etc/default/useradd
/etc/login.defs

read命令

-p:打印信息

-t:限定时间,-t5,5s内不输入就超时,退出read

-s:不回显。就像登录终端时,输入密码的时候不显示

-n:限制输入字符个数,-n6,只能输入6个字符

read是Bash的内置命令,也可以进行变量赋值。read主要可以用来提示用户输入信息,从而实现简单的交互过程。执行时将从标准输入设备(键盘)读取一行内容,并以空格为分隔符,将读入的个字段依次赋值给指定的变量(多余的内容赋给最后一个变量)。

$ read a b c
1 2 3 4 5 6     # 此部分是手动输入
$ echo $a
1
$ echo $b
2
$ echo $c
3 4 5 6

若指定变量只有一个,则将整行内容复制给此变量。

$ read a
1 2 3 4 5 6     # 此部分是手动输入
$ echo $a
1 2 3 4 5 6

为了使交互的方式更加的友好,提高易用性,read命令可以结合“-p”选项来设置提示信息,以便告知用户应该输入什么样的内容

$ read -p "请输入Yes或No:" a
请输入Yes或No:Yes
$ echo $a
Yes

变量状态赋值

主要用来判断变量是否为空

${VAR:-string}  如果VAR变量为空则返回string,不为空则返回变量值
${VAR:+string}  如果VAR变量不为空则返回string,为空则返回空
${VAR:=string}  如果VAR变量为空则重新赋值VAR变量值为string,不为空则返回变量值
${VAR:?string}  如果VAR变量为空则将string输出到stderr,不为空则返回变量值

设置变量的作用范围

默认情况下,新定义的变量只在当前的shell环境中有效,因此称为局部变量。当进入子程序或者新的shell环境时,局部变量将无法使用

$ echo $a
Yes
$ bash
$ echo $a

为了使用户定义的变量在所有的环境中都能够使用,减少重复设置的工作,可以通过内部命令export将指定的变量导出为全局变量。用户可以同时指定多个变量名作为参数,变量名之间以空格分隔,无需使用$引用变量

$ echo $CYJ $PJF
FeiYi Blog
$ export CYJ PJF
$ bash
$ echo $CYJ $PJF
FeiYi Blog

也可以直接使用export进行赋值,当然这么做的同时会定义变量和将变量变为全局变量

$ export a=5
$ bash
$ echo $a
5

shell输出格式化

echo:用于输出字符串的命令

选项:

-n:输出末尾不换行

-e:解释转义字符

$ echo -n "date: ";date +%F
date: 2021-04-06

shell中的转义字符

\a: 发出警告声。它确实是一段声音
# echo -e "\a"
\b: 删除前一个字符
###
for time in `seq 9 -1 0`; do
    echo -n -e "$time\b"
    sleep 1
done
###
\n和\r: 换行
\t: 插入tab
\v: 垂直制表,可结合\t使用
###
echo -e "name\tage\v\rFeiYi\t24"
name    age
FeiYi    24
###
# 一些不常用的就不写了

字符串颜色

脚本中echo显示内容带颜色显示,echo显示带颜色,需要使用参数-e

格式:

# 末尾的0m也是属性效果的意思,如果修改末尾的会将你接下来所有的操作都和该属性效果一致
# 所以,要对特定字符串进行修改,属性效果写在前面就可以
echo -e "\033[底色;字体颜色 字符串\033[0m"
echo -e "\033[属性效果\033[底色;字体颜色 字符串\033[0m"
echo -e "\033[属性效果\033[字体颜色 字符串\033[0m"
# 底色不能单独使用,必须配合字体颜色使用

40-47
40:黑色
41:红色
42:绿色
43:黄色
44:蓝色
45:紫色
46:天蓝色
47:白色

30-37
30m:黑色
31m:红色
32m:绿色
33m:黄色
34m:蓝色
35m:紫色
36m:天蓝色
37m:白色

0m:关闭所有属性
1m:设置高亮度
4m:下划线
5m:闪烁
7m:反显
8m:消隐

评论




正在载入...
PoweredHexo
HostedAliyun
DNSAliyun
ThemeVolantis
UV
PV
BY-NC-SA 4.0