2. 变量和引用

2.1 什么是变量

变量就是程序设计中一个可以变化的量。它会在内存中开辟一个空间,变量的名称引用是这个空间对应的地址,而这个地址中存储的就是变量的值。

2.2 变量的命名

在 Shell 中变量的名称可以由字母、数字和下划线组成,但是数字不能开头。原则上对变量的长度没有限制,但是一般不推荐变量名太长。尽量做到变量名称见名知意。

2.3 变量的作用范围

在 Shell 中命令的作用范围分为全局变量和局部变量,全局变量也叫系统变量,它在整个系统都可以用。而局部变量是需要在特定的环境中才可以使用的。

2.3.1 局部变量

局部变量也叫用户变量,或者叫临时变量。它只能在当前用户所在的环境中使用,或者在当前的会话中使用。

[root@openEuler ~]# name=lisi
[root@openEuler ~]# echo $name
lisi
[root@openEuler ~]# echo ${name}
lisi

# 产生一个子Shell环境
[root@openEuler ~]# bash
[root@openEuler ~]# echo $name

# 退出到父Shell环境
[root@openEuler ~]# exit
exit
[root@openEuler ~]# echo ${name}
lisi

2.3.2 全局变量

全局变量也叫系统变量,也可以称为永久变量。它是不区分用户环境的,对整个系统都有效。它需要定义在 /etc/profile 或者 /etc/bashrc 文件中通过 export 来导出。

我们在 /etc/profile 中定义一个变量,编写这个文件,在这个文件的最后添加如下内容:

[root@openEuler ~]# vim /etc/profile


export MyPath=/root

然后保存退出,然后测试是否能获取到定义的变量

[root@openEuler ~]# echo $MyPath

[root@openEuler ~]# . /etc/profile

[root@openEuler ~]# echo $MyPath
/root

# 切换用户及环境后再测试
[root@openEuler ~]# su - redhat
[redhat@openEuler ~]$ echo $MyPath
/root

[redhat@openEuler ~]$ exit
logout
[root@openEuler ~]# bash
[root@openEuler ~]# echo $MyPath
/root
[root@openEuler ~]# exit
exit

2.4 删除变量

当变量不再使用时,我们就需要把它删除,从而可以节省内存空间。

要删除变量就需要使用 unset 命令。它的语法为:

unset 变量名

使用示例:我们删除之前创建的 name 变量。

[root@openEuler ~]# echo $name
lisi
[root@openEuler ~]# unset name
[root@openEuler ~]# echo $name

[root@openEuler ~]# 

面试题:如下代码输出的结果是什么?

[root@openEuler ~]# cat test.sh
user1=`whoami`
[root@openEuler ~]# sh test.sh
[root@openEuler ~]# echo $user1

A. 当前用户
B. root
C. 空
D. 报错

2.5 变量的类型

Shell 是一种动态类型语言,也是一种弱类型的语言。所以在定义变量时,我们无须指定具体存放的值是什么类型(如:整数、小数、字符串等)。

但是在 Shell,变量也存在类型,它有以下几种类型:

  • 自定义变量
  • 环境变量
  • 只读变量
  • 位置变量
  • 预定义变量

2.5.1 自定义变量

在 Shell 中,通常情况下都是用户在使用时直接定义的变量,而无须先进行定义。

1)自定义变量的格式:
变量名=变量值

注意:

  1. 等号两边不能有空格
  2. 变量值如果是数字一般不加引号,如果是字符串推荐加引号;如果值包含有特殊字符或空格就必须要有引号
  3. 引号可以是以下几种:
    1. 单引号:被单引号包含的内容会原样输出
    2. 双引号:被双引号包含的内容会把变量的值替换后再输出
    3. 反引号:被反引号包含的命令执行的结果赋值给变量
2)查看变量的值

在 Shell 中查看变量的值有以下几种:

  • echo $变量名
  • echo ${变量名}
  • set 查看系统中所有变量
  • env 来查看系统环境变量
  • declare 来查看输出的所有变量、函数等。

使用示例:

[root@openEuler ~]# a=1
[root@openEuler ~]# echo $a
1
[root@openEuler ~]# echo ${a}
1
[root@openEuler ~]# ts=cs1
[root@openEuler ~]# echo $ts
cs1
[root@openEuler ~]# b = "hello"
-bash: b: command not found
[root@openEuler ~]# b ="hello"
-bash: b: command not found
[root@openEuler ~]# b= "hello"
-bash: hello: command not found
[root@openEuler ~]# b="hello"
[root@openEuler ~]# b='world'
[root@openEuler ~]# echo $b
world
[root@openEuler ~]# b=`pwd`
[root@openEuler ~]# echo $b
/root
[root@openEuler ~]# 

[root@openEuler ~]# env
SHELL=/bin/bash
HISTCONTROL=ignoredups
HISTSIZE=1000
HOSTNAME=openEuler
MyPath=/root
PWD=/root
LOGNAME=root
MOTD_SHOWN=pam
HOME=/root
LANG=en_US.UTF-8

对于单引号和双引号的区别:

[root@openEuler ~]# age=18
[root@openEuler ~]# name=list
[root@openEuler ~]# echo "$name,$age"
list,18
[root@openEuler ~]# echo '$name,$age'
$name,$age
[root@openEuler ~]# echo "\$name"
$name

3)使用declare来定义变量

格式如下:

declare attribute variable

attribute 它可以是 +/- 来定义,如果是 - 表示为这个属性设置值,如果是 + 表示取消此属性
有以下属性:
-p:表示所有变量的值
-i:将变量定义为整数,如果不能转换为整数则为 0
-r:将变量声明为只读变量
-a:将变量声明为数组

使用示例:

# 使用 -i 属性来声明定义的变量 n 的类型是一个整数,如果n的值不能转换为整数,则以0填充
[root@openEuler ~]# declare -i n
[root@openEuler ~]# n=5
[root@openEuler ~]# n=a
[root@openEuler ~]# echo $n
0
[root@openEuler ~]# n=4
[root@openEuler ~]# echo $n
4

# 使用 -r 属性来声明变量为只读的变量,对于只读变量来说,只能赋值一次,即它的值设置好后,就不能发生变量。
[root@openEuler ~]# declare -r name
[root@openEuler ~]# name=wangwu
-bash: name: readonly variable
[root@openEuler ~]# echo $name
list
[root@openEuler ~]# x=3
[root@openEuler ~]# declare -r x
[root@openEuler ~]# x=5
-bash: x: readonly variable


# 使用 -a 属性来声明变量是一个数组,数组是通过下标来设置或获取数据的,下标是从0开始,最大的下标是数组的长度 - 1。如果希望获取数组中所有的元素(值),可以使用 `数组名[@]` 的形式来获取
[root@openEuler ~]# declare -a arr
[root@openEuler ~]# arr[0]="hello"
[root@openEuler ~]# arr[1]="world"
[root@openEuler ~]# arr[2]="shell"
[root@openEuler ~]# echo $arr[0]
hello[0]
[root@openEuler ~]# echo ${arr[0]}
hello
[root@openEuler ~]# echo ${arr[2]}
shell
[root@openEuler ~]# echo ${arr[5]}

[root@openEuler ~]# echo ${arr[@]}
hello world shell
4)通过交互定义变量

在编写 Shell 脚本时,我们会用到与用户进行交互,将用户输入的值赋予我们定义的变量。此时我们可以使用 read 命令来实现。它的使用格式如下:

read -p "输入提示信息" 变量名称

使用示例:

[root@openEuler ~]# read -p 'please input your number:' num
please input your number:18
[root@openEuler ~]# echo $num
18
[root@openEuler ~]# 

除了这种在命令行中使用外,还可以在脚本中使用。格式如下:

[root@openEuler ~]# vim my_read.sh
[root@openEuler ~]# cat my_read.sh

#!/bin/bash
echo 'please input your number:'
read num
echo $num

[root@openEuler ~]# ll
total 40
-rw-------. 1 root root  881 Mar 16 20:10 anaconda-ks.cfg
drwxr-xr-x. 2 root root 4096 Mar 17 10:29 d1
-rwxr-xr-x. 1 root root   24 Mar 23 14:32 for_test.sh
-rw-r--r--. 1 root root   49 Mar 16 21:07 hehe.txt
-rw-r--r--. 1 root root   35 Mar 17 09:51 message.txt
-rw-r--r--. 1 root root   69 Mar 23 16:12 my_read.sh
-rwxr-xr-x. 1 root root   26 Mar 17 11:18 my.sh
-rw-r--r--. 1 root root  183 Mar 16 21:03 passwd
-rw-r--r--. 1 root root   34 Mar 23 15:33 test.sh
-rw-r--r--. 1 root root   54 Mar 17 10:21 test.txt
[root@openEuler ~]# bash my_read.sh 
please input your number:
20
20

2.5.2 环境变量

在 Shell 中环境变量分为系统环境变量和用户环境变量。系统变量的定义参数前变量范围中的内容。而用户环境变量我们可以用户的家目录下的 ~/.bash_profile 文件或 ~/.bashrc 文件中定义的变量。

在 Linux 中给我们内置了很多的环境变量,如:

# 执行命令时搜索的路径,以冒号进行分隔
[root@openEuler ~]# echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/

# 当前登录的用户名
[root@openEuler ~]# echo $USER
root

# 当前登录用户的家目录
[root@openEuler ~]# echo $HOME
/root

# 定义在命令模式下可以使用的命令行的长度
[root@openEuler ~]# echo $COLUMNS
156

# 命令存放的历史文件
[root@openEuler ~]# echo $HISTFILE
/root/.bash_history

其实,以上的这些系统变量我们可以使用 env 命令来查看:

[root@openEuler ~]# env
SHELL=/bin/bash
HISTCONTROL=ignoredups
HISTSIZE=1000
HOSTNAME=openEuler
MyPath=/root
PWD=/root
LOGNAME=root
MOTD_SHOWN=pam
HOME=/root
LANG=en_US.UTF-8
user1=root
SSH_CONNECTION=192.168.72.1 8175 192.168.72.150 22
SELINUX_ROLE_REQUESTED=
TERM=xterm
USER=root
SELINUX_USE_CURRENT_RANGE=
SHLVL=1
SSH_CLIENT=192.168.72.1 8175 22
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
SELINUX_LEVEL_REQUESTED=
MAIL=/var/spool/mail/root
SSH_TTY=/dev/pts/0
_=/usr/bin/env

2.5.3 只读变量

如果希望定义的变量在程序的执行过程中不会发生变量,此时就可以声明为只读变量。声明只读变量有两种方式:

  • declare -r 变量名称
  • readonly 变量名称

使用示例:

[root@openEuler ~]# n=1
[root@openEuler ~]# n=2
[root@openEuler ~]# readonly n
[root@openEuler ~]# n=3
-bash: n: readonly variable

当然,除我们先声明变量再变为只读外,也可以在声明的时候就定义为只读。

[root@openEuler ~]# readonly m=5
[root@openEuler ~]# m=6
-bash: m: readonly variable
[root@openEuler ~]# echo $m
5

对于只读变量来说,不能使用 unset 来删除。

2.5.4 位置变量

在很情况下,Shell 脚本执行时是需要接收用户输入的参数的,这时就需要使用到位置变量。

1)特殊变量
$#:表示参数的个数
$n:其中n表示大于0的数字,表示第 n 个参数
$0:表示这个被执行的脚本名称
$*:表示获取所有的参数列表
$@:表示获取所有的参数列表

使用示例:

# 编写一个脚本
[root@openEuler ~]# vim t1.sh
# 查看脚本内容
[root@openEuler ~]# cat t1.sh
#!/bin/bash

echo "total parameters: $#"
echo "first parameter: $1"
echo "second parameter: $2"
echo "filename is: $0"
echo "all arguments: $*"
echo "all arguments: $@"

# 运行脚本
[root@openEuler ~]# bash t1.sh python shell golang html
total parameters: 4
first parameter: python
second parameter: shell
filename is: t1.sh
all arguments: python shell golang html
all arguments: python shell golang html

2)$*$@的区别
[root@openEuler ~]# set -- "hello" "world" "shell"
[root@openEuler ~]# echo $*
hello world shell
[root@openEuler ~]# echo $@
hello world shell
[root@openEuler ~]# for fname in "$@"; do echo $fname; done
hello
world
shell
[root@openEuler ~]# for fname in "$*"; do echo $fname; done
hello world shell

从上面的输出结果可以发现 $*$@的异同如下:

  1. $*$@ 都可以获取到所有的参数列表,如果不加引号,它们没区别,如果加了引号区别如下:
  2. $@它是将参数以 “参数1” “参数2” 获取的,而 $*则是将参数以"参数1 参数2"的方式获取的
3)$? 执行结果状态

当脚本命令执行后,会有一个执行后的状态值,如果这个值为 0 则表示前一条命令执行成功,否则表示执行不成功,即有错误。

[root@openEuler ~]# cat t2.sh
cat: t2.sh: No such file or directory
[root@openEuler ~]# echo $?
1
[root@openEuler ~]# cat t1.sh
#!/bin/bash

echo "total parameters $#"
echo "first parameter $1"
echo "second parameter $2"
echo "filename is $0"
echo "all arguments $*"
echo "all arguments $@"
[root@openEuler ~]# echo $?
0
4)特殊状态变量

在 Shell 特殊状态变量有以下几个:

$$:返回脚本进程的PID
$!:获取上一个在后台的工作进程的PID
$_:保存的是之前所执行命令的最后一个参数

以上三个都不常用,大家了解即可。

[root@openEuler ~]# vim t2.sh
[root@openEuler ~]# cat t2.sh
#!/bin/bash

[ $# -ne 2 ] && {
	echo "must be two arguments"
	exit 3
}
echo ok
echo "current shell pid: $$"		# 输出当前脚本执行时产生的 PID 值

nohup ping www.baidu.com & 1>/dev/null		# 将 ping 命令的执行放到后台运行,并且不输出任何信息

echo $!		# 输出上一个后台运行的命令的 PID 值

将脚本编写好后,通过如下的方式来执行,从而得到如下的结果。

[root@openEuler ~]# bash t2.sh
must be two arguments

[root@openEuler ~]# bash t2.sh a b
ok
current shell pid: 2540		# 脚本运行的PID
2541						# ping命令运行的PID
nohup: appending output to 'nohup.out'
[root@openEuler ~]# ps -ef | grep ping			# 查看ping 进程
root        2541       1  0 17:10 pts/0    00:00:00 ping www.baidu.com
root        2543    1666  0 17:10 pts/0    00:00:00 grep --color=auto ping
[root@openEuler ~]# echo $_		# 输出上一次命令的最后一个参数
b

2.6 变量的特殊用法

在实际工作中,对变量的值还会有一些特殊的用法,例如对变量的值里德截取、替换、删除等。

要想实现这些功能,我们需要使用如下的格式:

${变量}					获取变量的值
${#变量}					返回变量的长度,即字符串的长度
${变量:start}				返回变量从start开始截取到变量最后,它是从 0 开始
${变量:start:length}		截取变量的值中从 start 开始,到 length 长度的内容
${变量#word}				将变量开头删除最短匹配的 word 子串
${变量##word}				将变量开头删除最长匹配的 word 子串
${变量%word}				从变量结尾删除最短的 word
${变量%%word}				从变量结尾删除最长的 word
${变量/parttern/string}	使用string代替第一个匹配的 parttern
${变量//parttern/string}	使用string代替所有匹配的 parttern

2.6.1 获取变量

${变量}					获取变量的值
${#变量}					返回变量的长度,即字符串的长度

使用示例:

[root@openEuler ~]# name="I am openEuler"
[root@openEuler ~]# echo ${name}
I am openEuler
[root@openEuler ~]# echo ${#name}
14

2.6.2 变量值截取

${变量:start}				返回变量从start开始截取到变量最后,它是从 0 开始
${变量:start:length}		截取变量的值中从 start 开始,到 length 长度的内容

使用示例:

[root@openEuler ~]# name="I am openEuler"
[root@openEuler ~]# echo ${name:2}
am openEuler
[root@openEuler ~]# echo ${name:2:5}
am op
[root@openEuler ~]# 

2.6.3 字符串删除

${变量#word}				将变量开头删除最短匹配的 word 子串
${变量##word}				将变量开头删除最长匹配的 word 子串
${变量%word}				从变量结尾删除最短的 word
${变量%%word}				从变量结尾删除最长的 word

使用示例:

[root@openEuler ~]# name="abcABC123ABCabc"
[root@openEuler ~]# echo ${name}
abcABC123ABCabc
[root@openEuler ~]# echo ${name#a*c}		# 匹配最短,它是从前往后删除
ABC123ABCabc
[root@openEuler ~]# echo ${name##a*c}		# 匹配最长,它是从前往后删除

[root@openEuler ~]# unset name
[root@openEuler ~]# name="abcABC123ABCabc"
[root@openEuler ~]# echo ${name}
abcABC123ABCabc
[root@openEuler ~]# echo ${name%a*c}		# 匹配最短,从后往前删除
abcABC123ABC
[root@openEuler ~]# echo ${name%%a*c}		# 匹配最长,从后往前删除

[root@openEuler ~]# 

2.6.4 字符串替换

${变量/parttern/string}	使用string代替第一个匹配的 parttern
${变量//parttern/string}	使用string代替所有匹配的 parttern

使用示例:

[root@openEuler ~]# str="hello, I like your 10000 years"
[root@openEuler ~]# echo ${str}
hello, I like your 10000 years
[root@openEuler ~]# echo ${str/o/O}
hellO, I like your 10000 years
[root@openEuler ~]# echo ${str//o/O}
hellO, I like yOur 10000 years

2.6.5 删除文件名

准备测试数据:

[root@openEuler ~]# mkdir sub_str
[root@openEuler ~]# cd sub_str/
[root@openEuler sub_str]# touch open_{1..5}_finish.jpg
[root@openEuler sub_str]# touch open_{1..5}_finish.png
[root@openEuler sub_str]# ll
total 0
-rw-r--r--. 1 root root 0 Mar 23 17:42 open_1_finish.jpg
-rw-r--r--. 1 root root 0 Mar 23 17:42 open_1_finish.png
-rw-r--r--. 1 root root 0 Mar 23 17:42 open_2_finish.jpg
-rw-r--r--. 1 root root 0 Mar 23 17:42 open_2_finish.png
-rw-r--r--. 1 root root 0 Mar 23 17:42 open_3_finish.jpg
-rw-r--r--. 1 root root 0 Mar 23 17:42 open_3_finish.png
-rw-r--r--. 1 root root 0 Mar 23 17:42 open_4_finish.jpg
-rw-r--r--. 1 root root 0 Mar 23 17:42 open_4_finish.png
-rw-r--r--. 1 root root 0 Mar 23 17:42 open_5_finish.jpg
-rw-r--r--. 1 root root 0 Mar 23 17:42 open_5_finish.png

需求:去掉所有文件中的 _finish 字符串

分析:
1. 可以通过 mv 命令来修改,如:
mv open_1_finish.jpg open_1.jpg

2. 我们要获取这个文件
f=open_1_finish.jpg

3. 通过字符串删除来实现
${f//_finish/}

实现:

# 查看当前目录下所有的文件
[root@openEuler sub_str]# ls
open_1_finish.jpg  open_2_finish.jpg  open_3_finish.jpg  open_4_finish.jpg  open_5_finish.jpg
open_1_finish.png  open_2_finish.png  open_3_finish.png  open_4_finish.png  open_5_finish.png

# 循环这些文件并显示
[root@openEuler sub_str]# for f in `ls`
> do
> echo ${f}
> done
open_1_finish.jpg
open_1_finish.png
open_2_finish.jpg
open_2_finish.png
open_3_finish.jpg
open_3_finish.png
open_4_finish.jpg
open_4_finish.png
open_5_finish.jpg
open_5_finish.png

# 通过循环来去掉 _finish 字符,但它并没有真正的修改磁盘中的文件,只是在内存中修改了
[root@openEuler sub_str]# for f in `ls`; do echo ${f//_finish/}; done
open_1.jpg
open_1.png
open_2.jpg
open_2.png
open_3.jpg
open_3.png
open_4.jpg
open_4.png
open_5.jpg
open_5.png
[root@openEuler sub_str]# ll
total 0
-rw-r--r--. 1 root root 0 Mar 23 17:42 open_1_finish.jpg
-rw-r--r--. 1 root root 0 Mar 23 17:42 open_1_finish.png
-rw-r--r--. 1 root root 0 Mar 23 17:42 open_2_finish.jpg
-rw-r--r--. 1 root root 0 Mar 23 17:42 open_2_finish.png
-rw-r--r--. 1 root root 0 Mar 23 17:42 open_3_finish.jpg
-rw-r--r--. 1 root root 0 Mar 23 17:42 open_3_finish.png
-rw-r--r--. 1 root root 0 Mar 23 17:42 open_4_finish.jpg
-rw-r--r--. 1 root root 0 Mar 23 17:42 open_4_finish.png
-rw-r--r--. 1 root root 0 Mar 23 17:42 open_5_finish.jpg
-rw-r--r--. 1 root root 0 Mar 23 17:42 open_5_finish.png

# 结合 mv 命令来一个文件一个文件的修改  mv open_1_finish.jpg open_1.jpg
# open_1_finish.jpg 文件名称就是每次循环所得到的文件名 ${f}
# open_1.jpg 是通过 ${f//_finish/} 替换来到的
[root@openEuler sub_str]# for f in `ls`; do mv ${f} ${f//_finish/}; done
[root@openEuler sub_str]# for f in `ls`; do mv ${f} ${f##_finish}; done
[root@openEuler sub_str]# for f in `ls`; do mv ${f} ${f%%_finish}; done
[root@openEuler sub_str]# ll
total 0
-rw-r--r--. 1 root root 0 Mar 23 17:42 open_1.jpg
-rw-r--r--. 1 root root 0 Mar 23 17:42 open_1.png
-rw-r--r--. 1 root root 0 Mar 23 17:42 open_2.jpg
-rw-r--r--. 1 root root 0 Mar 23 17:42 open_2.png
-rw-r--r--. 1 root root 0 Mar 23 17:42 open_3.jpg
-rw-r--r--. 1 root root 0 Mar 23 17:42 open_3.png
-rw-r--r--. 1 root root 0 Mar 23 17:42 open_4.jpg
-rw-r--r--. 1 root root 0 Mar 23 17:42 open_4.png
-rw-r--r--. 1 root root 0 Mar 23 17:42 open_5.jpg
-rw-r--r--. 1 root root 0 Mar 23 17:42 open_5.png

2.7 扩展变量

在 Shell中还有一些扩展变量的使用方式。

${变量:-word}		如果变量值为空,则返回 word 字符串,如果不为空则返回变量本身的值
${变量:=word}		如果变量值为空,则将word替换变量后并返回
${变量:?word}		如果变量值为空,则word将当作stderr输出,否则输出变量的值
${变量:+word}		如果变量值为空,则什么都不做,否则返回 word

使用示例:

# ${变量:-word}
[root@openEuler ~]# name=lisi
[root@openEuler ~]# echo $name
lisi
[root@openEuler ~]# name1=${name:-wangwu}
[root@openEuler ~]# echo $name1
lisi
[root@openEuler ~]# unset name
[root@openEuler ~]# echo $name

[root@openEuler ~]# name1=${name:-wangwu}
[root@openEuler ~]# echo $name1
wangwu

# ${变量:=word}
[root@openEuler ~]# name=lisi
[root@openEuler ~]# echo $name
lisi
[root@openEuler ~]# name1=${name:=zhangsan}
[root@openEuler ~]# echo $name1
lisi
[root@openEuler ~]# unset name
[root@openEuler ~]# name1=${name:=zhangsan}
[root@openEuler ~]# echo $name
zhangsan
[root@openEuler ~]# echo $name1
zhangsan

# ${变量:?word}
[root@openEuler ~]# name=haha
[root@openEuler ~]# echo $name
haha
[root@openEuler ~]# name1=${name:?hehe}
[root@openEuler ~]# echo $name
haha
[root@openEuler ~]# echo $name1
haha
[root@openEuler ~]# unset name
[root@openEuler ~]# name1=${name:?hehe}
-bash: name: hehe

# ${变量:+word}	
[root@openEuler ~]# name=xiaowang
[root@openEuler ~]# echo $name
xiaowang
[root@openEuler ~]# name1=${name:+xiaoli}
[root@openEuler ~]# echo $name
xiaowang
[root@openEuler ~]# echo $name1
xiaoli
[root@openEuler ~]# unset name
[root@openEuler ~]# name1=${name:+xiaoli}
[root@openEuler ~]# echo $name

[root@openEuler ~]# echo $name1

[root@openEuler ~]# 

这四个一般用于对变量值的判断处理。

实际案例:判断变量的值,如果值为空则返回后面的字符信息。

[root@openEuler ~]# echo $hana

[root@openEuler ~]# result=${hana:-haha}
[root@openEuler ~]# echo $result
haha
[root@openEuler ~]# hana="nihao"
[root@openEuler ~]# result=${hana:-haha}
[root@openEuler ~]# echo $result
nihao
  • 15
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

acro_09

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值