Linux系统中shell处理变量详解

时间:2024-10-14 11:25:30

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