Linux系统中shell处理变量详解
- 一、shell中变量介绍
- 1.1 变量简介
- 1.2 环境变量和本地变量
- 1.3 预定义变量
- 二、本地变量的使用
- 2.1 本地变量介绍
- 2.2 定义本地变量
- 2.3 查看本地变量
- 2.4 取消环境变量
- 2.5 查询变量值
- 2.6 本地变量的使用
- 三、环境变量
- 3.1 环境变量介绍
- 3.2 定义环境变量
- 3.3 查看环境变量
- 3.4 取消环境变量
- 3.5 查询设置的环境变量值
- 3.6 变量在shell脚本使用
- 四、使用echo输出变量方式
- 4.1 直接输出变量
- 4.2 使用反斜杠转义
- 4.3. 使用单引号与双引号
- 4.4 使用命令替换
- 4.5 换行输出
- 4.6 使用变量扩展
- 4.7 使用复合命令
- 五、引用变量的不同方式
- 5.1 使用`$()`方式
- 5.2 使用 `$(())`方式
- 5.3 使用`${}`方式
- 5.4 三种方式总结
- 六、`${}`方式扩展用法
- 6.1 提取字符串
- 6.2 匹配前缀删除
- 6.3 匹配后缀删除
- 6.4 变量默认赋值
一、shell中变量介绍
1.1 变量简介
在
shell
脚本中,变量
是存储数据的容器。变量可以包含各种类型的数据,如字符串、数字或数组等。在shell脚本中,可以通过给变量赋值来存储数据,然后可以在脚本中使用变量来引用这些数据。变量还可以通过运算、合并或比较等操作进行处理。在使用变量时,可以通过变量名来引用变量的值。
1.2 环境变量和本地变量
1.本地变量
-
本地变量
:由用户自定义的变量名和变量值。又称为局域变量,仅在当前shell中有效,不会继承到子shell。
2.环境变量
-
环境变量
:全局变量在全局范围内可见,在声明全局变量时,不需要加任何修饰词,仅在当前shell和子shell中有效。
1.3 预定义变量
这个表格总结了预定义变量的功能和用法
变量 | 符号 | 描述 |
---|---|---|
命令行参数数量 | $# |
表示命令行中位置参数的个数。 |
所有位置参数内容 | $* |
表示所有位置参数的内容,这些内容作为一个整体。 |
列出所有位置参数 | $@ |
表示列出所有位置参数,每个参数作为单独的项。 |
上一条命令的返回状态 | $? |
表示前一条命令执行后的返回状态,返回值为 0 表示执行成功,非 0 值表示出现异常。 |
当前脚本或程序名称 | $0 |
表示当前执行的脚本或程序的名称。 |
当前进程的进程号 | $$ |
表示返回当前进程的进程号。 |
上一个后台进程的进程号 | $! |
返回最后一个后台进程的进程号。 |
二、本地变量的使用
2.1 本地变量介绍
本地变量 (Local Variables)
- 定义: 局部变量是在特定的Shell或函数内部定义的变量,它们的作用范围仅限于定义它们的上下文中。
- 作用范围: 局部变量仅在其定义的Shell或函数内部有效。
- 生命周期: 局部变量在其定义的上下文结束时(例如,当一个函数返回或一个子Shell退出时)就会失效。
-
声明与修改: 可以直接赋值来声明局部变量,也可以使用
local
关键字。
2.2 定义本地变量
在shell命令行,执行以下命令,定义本地变量。
- 定义本地变量
testaa_local="this is a local variable"
- 1
2.3 查看本地变量
我们可以使用set命令过滤查询刚才设置的本地变量,set列出的是所有变量,包括本地变量和环境变量。
[root@openEuler ~]# set |grep testaa
testaa_local='this is a local variable'
- 1
- 2
2.4 取消环境变量
可以使用unset命令取消环境变量
unset testaa_loacl
- 1
2.5 查询变量值
我们使用$符号来应用变量,使用echo命令来查看变量值。
[root@openEuler ~]# echo "$testaa_local"
this is a local variable
- 1
- 2
2.6 本地变量的使用
访问: 本地(局部)变量只能在其定义的上下文中访问。
- 我们编辑一个简单脚本·test_loacl01.sh·
vim test_loacl01.sh
- 1
#!/bin/bash
myLocalVar="local value"
function myFunction {
local localVar="function-local value"
echo "$localVar"
}
myFunction
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 执行脚本
[root@openEuler ~]# sh test_loacl01.sh
function-local value
- 1
- 2
三、环境变量
3.1 环境变量介绍
环境变量 (Environment Variables)
- 定义: 环境变量是在操作系统级别定义的变量,它们对于所有运行中的进程都是可见的,并且可以在子进程间继承。
- 作用范围: 环境变量在整个系统范围内都是有效的,并且可以在任何Shell脚本或程序中访问。
- 生命周期: 环境变量通常在整个系统的运行周期内保持有效,除非显式地更改或清除它们。
-
声明与修改: 使用
export
命令声明或修改环境变量。
3.2 定义环境变量
执行以下命令,使用export定义环境变量。
export ATEST=aa587
- 1
3.3 查看环境变量
只用env查看环境变量
[root@openEuler ~]# env |grep ATEST
ATEST=aa587
- 1
- 2
3.4 取消环境变量
执行以下命令,取消环境变量。
unset ATEST
- 1
3.5 查询设置的环境变量值
使用echo命令,查询刚才设置环境变量值。
[root@openEuler ~]# echo "$ATEST"
aa587
- 1
- 2
3.6 变量在shell脚本使用
如果我们想要在一个Shell脚本中使用环境变量和本地变量,可以使用以下方法。
vim
- 1
#!/bin/bash
##########################################################
# File Name:
# Version: V1.0
# Author: jeven
# Email: admin@
# Created Time: 2024-07-25 00:33:57
# Description:
##########################################################
# 定义一个环境变量
export ENV_VAR="environment variable"
# 定义一个局部变量
LOCAL_VAR="local variable"
# 输出环境变量
echo "Environment Variable: $ENV_VAR"
# 定义一个函数并使用局部变量
function printLocal {
local localVar="function-local variable"
echo "Local Variable in Function: $localVar"
}
# 调用函数
printLocal
# 输出局部变量(在主脚本中仍然可用)
echo "Local Variable in Script: $LOCAL_VAR"
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 执行脚本
[root@openEuler ~]# sh
Environment Variable: environment variable
Local Variable in Function: function-local variable
Local Variable in Script: local variable
- 1
- 2
- 3
- 4
在这个例子中,
ENV_VAR
是一个环境变量,可以在整个脚本中访问,而LOCAL_VAR
是一个局部变量,仅在脚本的*上下文中可用。localVar
则是在printLocal
函数内部定义的局部变量,仅在该函数内部有效。
四、使用echo输出变量方式
4.1 直接输出变量
在Linux shell脚本或命令行中,使用
echo
命令来输出变量的内容是一种常见的做法。直接输出变量,这是最简单的方式,直接在echo
后面加上变量名即可。注意,变量名前面需要加上美元符号$
以表示这是一个变量而不是普通的文本。如果变量名包含空格或者特殊字符,应该使用双引号"
把变量包起来。
variable="Hello, world!"
echo "$variable"
- 1
- 2
4.2 使用反斜杠转义
如果要在输出中包括双引号本身或其他特殊字符,可以使用反斜杠
\
进行转义。
message='"Hello, world!" she said.'
echo "$message"
- 1
- 2
4.3. 使用单引号与双引号
-
单引号 (
'...'
):不会解析变量,会原样输出。 -
双引号 (
"..."
):会解析变量并替换其值。
var="world"
echo 'Hello, $var!' # 输出: Hello, $var!
echo "Hello, $var!" # 输出: Hello, world!
- 1
- 2
- 3
4.4 使用命令替换
命令替换允许你将命令的结果作为变量的一部分使用。
date_var=$(date)
echo "Today is $date_var"
- 1
- 2
4.5 换行输出
echo输出变量值时,换行输出。
A=100
B=200
C=300
echo -e "$A\n$B\n$C"
- 1
- 2
- 3
- 4
- 5
4.6 使用变量扩展
除了
echo
外,还可以利用shell的变量扩展特性。
greeting="Hello, world!"
echo "${greeting}"
- 1
- 2
4.7 使用复合命令
可以使用复合命令结构,例如
{ ... ; }
,以确保echo
和变量赋值在同一命令行内完成。
[root@openEuler ~]# { greeting="Hello, world!"; echo "$greeting"; }
Hello, world!
- 1
- 2
五、引用变量的不同方式
5.1 使用$()
方式
在Linux shell 脚本中,$()
, $(())
, 和 ${}
都是用来处理变量和表达式的不同方式。
- 用途: 用于命令替换(command substitution),即将一个命令的输出结果作为变量的值。
-
语法:
$()
或者使用旧式的反引号`
(backticks)。 - 示例:
[root@openEuler ~]# result=$(ls -l)
[root@openEuler ~]# echo "$result"
total 120
-rw-r--r--. 1 root root 95400 Jul 17 22:31 7.1.
-rw-------. 1 root root 1060 Jun 27 15:51
-rwxr-x--x. 1 root root 0 Jul 17 17:02
drwxr-xr-x. 2 root root 4096 Jul 23 22:14 filestash
-rw-r--r--. 1 root root 1781 Jul 17 22:42 info_system.txt
drwxrwxr-x. 3 root root 4096 Aug 3 2020 neofetch-7.1.0
-rw-r--r--. 1 root root 745 Jul 25 00:38
-rw-r--r--. 1 root root 145 Jul 24 23:44 test_loacl01.sh
[root@openEuler ~]#
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 也可以使用以下方式来应用变量
result=`ls -l`
echo "$result"
- 1
- 2
5.2 使用 $(())
方式
-
用途: 用于算术运算,是算术表达式的一种形式。
-
语法:
$(())
。 -
示例:
AA=10 BB=20 sum=$(($AA + $BB)) echo "$sum"
- 1
- 2
- 3
- 4
5.3 使用${}
方式
- 用途: 用于变量扩展、参数扩展以及一些特殊的变量操作。
-
语法:
${}
。 - 示例:
使用
${}
方式,可以直接引用变量。
[root@openEuler ~]# name="John Doe"
[root@openEuler ~]# echo "${name}"
John Doe
- 1
- 2
- 3
参数扩展
:
- 用途: 可以对变量值进行各种修改和过滤。
-
语法:
${var:offset:length}
,${var#pattern}
,${var##pattern}
, 等等。
5.4 三种方式总结
这些特性在编写复杂的shell脚本时非常有用,可以根据需要选择合适的方式来处理变量和表达式。
-
$()
用于命令替换,获取命令的输出结果。 -
$(())
专门用于执行算术运算。 -
${}
用于一般的变量扩展和参数扩展,包括一些特殊的变量操作。
六、${}
方式扩展用法
6.1 提取字符串
1. 提取字符串:${var:offset:length}
${var:offset:length}
这个扩展用于从变量 var 中提取子字符串。offset 指定从哪个位置开始提取(索引从 0 开始),而 length 指定要提取多少个字符。
[root@openEuler ~]# var="Hello, world!"
[root@openEuler ~]# echo "${var:7:5}"
world
- 1
- 2
- 3
6.2 匹配前缀删除
- 修改变量1—匹配前缀:${var#pattern}
${var#pattern}
这个扩展用于删除变量 var 的最前缀匹配 pattern 的部分。它只删除第一个匹配的部分。#/home/ 是模式,表示删除最前面的 /usr},结果是 “/local/bin”。
path="/usr/local/bin"
echo "${path#/usr}" # 输出 /local/bin
- 1
- 2
- 修改变量2—匹配前缀:${var##pattern}
${var##pattern}
这个扩展与 ${var#pattern} 类似,但它删除变量 var 的所有前缀匹配 pattern 的部分。换句话说,它会删除尽可能多的匹配部分。
var="/home/user/documents/home"
echo "${var##*/}" # 输出 "documents/home"
- 1
- 2
解释:
var 的值是 "/home/user/documents/home"。
##*/ 是模式,表示删除所有以 / 开头的部分。
第一次匹配删除了开头的 /home/,留下了 "user/documents/home"。
接下来继续匹配,直到无法再匹配为止。
结果是 "documents/home"。
- 1
- 2
- 3
- 4
- 5
- 6
6.3 匹配后缀删除
- 修改变量—匹配后缀:${var%pattern}
${var%pattern}删除 var 最后面匹配 pattern 的部分。
var="/home/user/documents"
echo "${var%/*}" # 输出 "/home/user"
- 1
- 2
6.4 变量默认赋值
- 设置变量值:${var:=word}
${var:=word}:如果 var 未设置或为空,则将其设置为 word;否则返回 var 的值。
[root@openEuler ~]# var=""
[root@openEuler ~]# echo "${var:=Hello, world}"
Hello, world
[root@openEuler ~]# echo "$var"
Hello, world
- 1
- 2
- 3
- 4
- 5
- ${var:-default}
如果 var 为空或未设置,则返回 default;否则返回 var 的值。
[root@openEuler ~]# var=""
[root@openEuler ~]# echo "${var:-hello}"
hello
[root@openEuler ~]# var="aa"
[root@openEuler ~]# echo "${var:-hello}"
aa
- 1
- 2
- 3
- 4
- 5
- 6
- ${var:+word}
如果 var 已设置且非空,则返回 word;否则返回空字符串。
[root@openEuler ~]# var="aa"
[root@openEuler ~]# echo "${var:+hello}"
hello
[root@openEuler ~]# var=""
[root@openEuler ~]# echo "${var:+hello}"
[root@openEuler ~]#
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- ${var:?word}
如果 var 已设置,则打印 word 并退出 shell 脚本;否则会返回-bash: word is not set.
[root@openEuler ~]# name="John"
[root@openEuler ~]# echo "Hello, ${name:?Name is not set.}"
Hello, John
[root@openEuler ~]# echo "Hello, ${age:?Age is not set.}"
-bash: age: Age is not set.
- 1
- 2
- 3
- 4
- 5