新手也能看懂的:Shell 脚本编程

一,Shell 介绍

1.1 shell 概念

        在类 Unix 操作系统(如 Linux)中,Shell 是一个命令行解释器(Command-Line Interpreter),它为用户提供了一个与操作系统内核交互的接口。用户通过 Shell 向系统发出命令,Shell 解析并传递这些命令给操作系统执行。

        Shell 是一种“外壳”,包裹在操作系统内核之外,用于接收用户输入、解释命令、管理程序运行。

简单一点就是:

        Shell 是一种运行在 Linux 系统上的命令行解释器,它不仅可以执行单条命令,还可以将多条命令进行组织、编排,形成具备逻辑控制能力的脚本,实现批量处理与自动化操作

Shell 的主要功能

  1. 命令解析与执行
    Shell 接收用户输入的命令,并将其翻译为内核可以理解的系统调用。
  2. 脚本编程能力
    Shell 支持编写具有流程控制(如条件判断、循环、函数等)的脚本,广泛用于任务自动化与系统管理。
  3. 环境管理
    Shell 允许配置环境变量、启动程序、加载资源配置文件等操作。
  4. 程序控制
    Shell 能够调用、调度和管理进程,包括前台、后台、管道和重定向等功能。

Shell = 命令行界面 + 命令解释器

你在终端输入的每一句命令,都是 Shell 在帮你执行。


1.2 shell 和 平日的命令有什么区别

🧐 Shell 脚本和命令行有什么区别?

其实核心区别可以简单理解成:

命令行是你“一条一条”地敲;Shell 脚本是你“提前写好一堆命令”一次性执行。


✅ 具体区别如下:

对比项

命令行

Shell 脚本

使用方式

在终端一条条输入

写在 .sh文件中统一执行

适用场景

临时操作、调试

自动化任务、重复工作、定时执行

可读性与复用性

操作完就没了

可以保存、修改、复用

支持逻辑控制

有限(需要逐条输入)

完整支持流程控制语句(if、for、while 等)

变量/函数支持

临时变量

支持变量、函数封装

还是这句话:

        Shell 是一种运行在 Linux 系统上的命令行解释器,它不仅可以执行单条命令,还可以将多条命令进行组织、编排,形成具备逻辑控制能力的脚本,实现批量处理与自动化操作

二,开始编程

        在学习shell编程之前,我们先安装一个用于校验shell 语法的校验工具。shellcheck。命令如下:

# Debian/Ubuntu
sudo apt install shellcheck

# Red Hat/CentOS/Fedora
sudo yum install ShellCheck / sudo dnf install ShellCheck

# MacOS (使用 Homebrew)
brew install shellcheck

        在线地址:ShellCheck – shell script analysis tool

2.1 shell 注意事项

        在编写 shell 脚本的一定要指定shell脚本的解析器。

#!/bin/bash  # shell 的指定的解释器是 bash, 其路径在/bin/
name="Alice"
echo "Hello, ${name}!"   # 输出:Hello, Alice!

🧠 常见的 Shell 脚本解释器列表(Shebang 用法)

在脚本文件的第一行写上

#!<解释器路径>

用于指定该脚本由哪个解释器运行。

Shebang 语句

描述

#!/bin/bash

Bash Shell,最常用的解释器,Linux 默认配置之一

#!/bin/sh

标准 Shell,是 Bourne Shell 的简化版本,兼容性好

#!/bin/zsh

Z Shell,功能更强大的交互式 shell,支持自动补全等

#!/bin/dash

Debian 系的轻量级 shell,常用作 /bin/sh 替代

#!/usr/bin/env bash

推荐写法,自动在环境变量中查找 bash 所在路径

#!/usr/bin/env sh

查找 sh 的路径,适用于不同平台

#!/usr/bin/env zsh

用于 zsh 的通用平台兼容写法

#!/bin/ksh

Korn Shell,历史比较悠久,用于企业脚本系统

#!/bin/csh

C Shell,语法类似于 C,较少使用

#!/bin/tcsh

C Shell 的增强版本

#!/usr/bin/perl

指定用 Perl 解释器执行脚本

#!/usr/bin/python

用 Python 解释器运行脚本(非 Shell,但也可做脚本解释)

2.2 🧾shell 脚本的变量定义的介绍

🧩 2.2.1 变量定义的基本语法

变量名=值

⚠️ 等号两边不能有空格!

✅ 正确示例:
#!/bin/bash
name="Tom"
age=25
❌ 错误示例:
#!/bin/bash
name = "Tom"   # 错误,等号前后不能有空格

#!/bin/bash 
name="Alice"
echo "Hello, ${name}!"   # 输出:Hello, Alice!

🧠 2.2.2 变量的引用

echo $变量名
示例:
#!/bin/bash
echo $name    # 输出:Tom

如果变量名后面紧跟字符,推荐使用花括号括起来避免歧义:

#!/bin/bash
echo "My name is ${name}man"  # 避免输出 $nameman

🧾 2.2.3 $name 和 ${$name} 引用区别

        在 Shell 脚本或类 Bash 语言中,$name${name} 是用于变量引用的两种语法。这里是它们的主要区别和使用场景:


$name

        这是最常见、最简洁的变量引用方式。

#!/bin/bash
name="world"
echo "Hello, $name"
# 输出: Hello, world

${name}

这是 更通用、推荐的写法,尤其在变量后面紧跟其他字符时,用花括号 {} 能避免歧义。

#!/bin/bash
name="world"
echo "Hello, ${name}123"
# 输出: Hello, world123

# 如果用 $name123,Shell 会以为你是想引用名为 name123 的变量:
echo "Hello, $name123"
# 如果没有 name123,会输出 Hello, (空值)

🚫 ${$name}

这是 不合法或不推荐的用法,但它背后的意图可能是“变量的变量”,即 动态变量名

比如:

#!/bin/bash
name="user"
user="Alice"

echo ${!name}
# 输出: Alice

解释:

  • $name 的值是 user
  • ! 表示引用变量名为 user 的值
  • 所以 ${!name} 等价于 ${user},输出 Alice

${$name} 是错误的语法,Shell 会报错或输出空。


总结表:

表达式

含义

$name

简单引用变量

${name}

更安全、更通用的变量引用方式

${$name}

错误的语法(可能想实现变量变量)

${!name}

有效的“变量变量”写法(间接引用)


2.3 shell 脚本的常用全局变量的介绍

在上面我们学习了shell脚本中怎么定义变量,以及怎么引用变量。在Linux 系统当中,也提供一些系统常用的全局变量提供给开发者使用。我们只需要进行引用全局变量即可。

命令查看全局变量
printenv         # 显示所有环境变量
env              # 同上
set              # 显示所有变量(包括环境变量和 shell 本地变量)
declare -x       # 只显示 export 的变量(全局)
常见全局变量列表

变量名

含义

HOME

当前用户的主目录,如 /home/username

USER

当前登录的用户名

LOGNAME

当前登录的用户名(与 USER 通常一致)

SHELL

当前使用的 shell 路径(如 /bin/bash

PATH

可执行程序的搜索路径,多个路径用 :分隔

PWD

当前工作目录(Print Working Directory)

OLDPWD

上一次的工作目录

LANG

默认语言和字符集设置,如 en_US.UTF-8

TERM

终端类型(如 xterm-256color

EDITOR

默认编辑器(如 vim

HOSTNAME

当前主机的名称

UID

当前用户的用户 ID

HOME

用户的主目录路径

DISPLAY

图形显示设置(X11)

MAIL

当前用户的邮箱路径

SHLVL

Shell 嵌套层级(例如你开了几个 subshell)

PS1

Shell 提示符的格式

IFS

字段分隔符(默认是空格、Tab、换行)

示例:
#!/bin/bash
remark="自定义变量"
username=$(whoami) # 调用执行 Linux 的 whoami 命令

if [ "${username}" = "root" ]; then
        echo "you are root"
else
        echo "you are ${username}"

fi

echo " ========================= global var ================================= "

echo " 当前用户的home目录:                     ${HOME} "
echo " 当前用户名:                             ${USER} "
echo " 当前用户ID:                              ${UID} "
echo " 当前 shell 路径(如/bin/bash):           ${SHELL} "
echo " 当前工作目录:                           ${PWD} "
echo " 可执行文件查找路径(which) :             ${PATH} "
echo " 主机名:                                  ${HOSTNAME} "
~                                                                     

还可以直接使用

[toast@localhost shell-script]$ echo $USER
toast
[toast@localhost shell-script]$ echo $HOME
/home/toast

自定义全局变量
[toast@localhost shell-script]$ vim my-token.sh
#!/bin/bash

# 定义全局变量(环境变量)
export MY_TOKEN_VAR="TOKEN-TOAST"

# 启动一个子进程来验证变量是否可用
bash -c 'echo "来自子 Shell 的 GREETING: $GREETING"'

执行结果

[toast@localhost shell-script]$ ./my-token.sh 
来自子 Shell 的 GREETING: TOKEN-TOAST # 另外一个程序读取到全局变量的 MY_TOKEN_VAR

如果想直接在终端交互界面直接使用全局变量。需要定义到环境配置文件上面。如下:

文件

是什么?

作用说明

~/.bashrc

Bash 的初始化脚本

每次你打开 交互式 Bash 终端 都会执行它

~/.zshrc

Zsh 的初始化脚本

每次你打开 Zsh 终端 都会执行它

~/.profile

通用 shell 登录脚本

适用于登录 Shell,有时 GUI 启动的也走它

/etc/profile

系统级环境初始化脚本

所有用户的登录 Shell 都会执行

【查看当前小编的环境】小编使用的是 Bash Shell 的终端进行交互

[toast@localhost shell-script]$ vim ~/
.bash_history  .bash_profile  .config/       file.sh        test.txt       
.bash_logout   .bashrc        .viminfo       shell-script/  

因为我是 普通用户(toast)在用 Bash 登录交互式 shell,所以:

👉 ~/.bashrc 是配置「交互式 shell 环境变量」的首选位置

所有文件作用一览

文件名

作用

你该用吗?

.bashrc

每次打开终端都会执行(交互式 shell)

✅ 推荐使用

.bash_profile

登录 shell 执行一次,通常用于一次性加载 .bashrc

⚠️ 可选

.bash_logout

用户退出 shell 时执行的脚本

❌ 基本不用

.bash_history

历史命令记录,不是用来写变量的

❌ 不要动

.viminfo

Vim 的历史/缓存记录

❌ 不相关

🛠 怎么用 .bashrc 定义环境变量?

1. 打开 .bashrc
vim ~/.bashrc
2. 添加你要的环境变量,例如:

3. 保存后让它立即生效:
[toast@localhost shell-script]$ source ~/.bashrc  # 保存后让它立即生效
[toast@localhost shell-script]$ echo $MY_TOKEN_VAR # 验证
TOKEN-TOAST

2.3 shell 脚本分支语句的介绍

        在 Shell 脚本中,**分支语句(条件语句)**是用来根据条件执行不同代码块的结构,就像其他编程语言中的 if-elseswitch-case 一样。掌握 Shell 分支语句对于编写逻辑清晰、自动化强的脚本非常关键。


🌱 2.3.1 基本的 if 语句

单分支 if
if [ 条件 ]; then
  命令
fi

🔹 示例:

if [ -f "test.txt" ]; then
  echo "文件存在"
fi

if-else 语句
if [ 条件 ]; then
  命令1
else
  命令2
fi

🔹 示例:

if [ "$USER" = "root" ]; then
  echo "管理员登录"
else
  echo "普通用户登录"
fi

if-elif-else 语句
if [ 条件1 ]; then
  命令1
elif [ 条件2 ]; then
  命令2
else
  命令3
fi

🔹 示例:

if [ "$score" -ge 90 ]; then
  echo "优秀"
elif [ "$score" -ge 60 ]; then
  echo "及格"
else
  echo "不及格"
fi

🔄 2.3.2 case 分支语句(类似 switch)

当要根据一个变量的不同值来选择不同分支时,用 case 比较方便:

case "$变量" in
  模式1)
    命令1
    ;;
  模式2)
    命令2
    ;;
  *)
    默认命令
    ;;
esac

🔹 示例:

read -p "请输入(y/n): " answer
case "$answer" in
  y|Y)
    echo "你选择了 Yes"
    ;;
  n|N)
    echo "你选择了 No"
    ;;
  *)
    echo "无效输入"
    ;;
esac

🔁 2.3.3 条件判断表达式详解

        下面是 Shell 脚本中 字符串、文件、数字 相关的判断条件分类整理,清晰易查,适合学习和实战中快速参考 👇


🧵 字符串相关判断

条件表达式

含义

示例

[ -z "$str" ]

字符串为空

-z "$name"

[ -n "$str" ]

字符串非空

-n "$input"

[ "$a" = "$b" ]

字符串相等

[ "$name" = "admin" ]

[ "$a" != "$b" ]

字符串不等

[ "$env" != "prod" ]

[[ "$a" =~ regex ]]

字符串是否匹配正则(高级)

[[ "$email" =~ "@[a-z]+\." ]]

🔸 示例:

str="hello"
if [ -n "$str" ]; then
  echo "字符串不为空"
fi

📂 文件相关判断

条件表达式

含义

示例

[ -e file ]

文件是否存在

[ -e "./config.txt" ]

[ -f file ]

是否为普通文件

[ -f "./data.log" ]

[ -d dir ]

是否为目录

[ -d "./backup/" ]

[ -r file ]

是否可读

[ -r "/etc/passwd" ]

[ -w file ]

是否可写

[ -w "./notes.txt" ]

[ -x file ]

是否可执行

[ -x "./run.sh" ]

[ file1 -nt file2 ]

file1 比 file2 新

[ a.txt -nt b.txt ]

[ file1 -ot file2 ]

file1 比 file2 旧

[ a.txt -ot b.txt ]

🔸 示例:

if [ -f "run.sh" ] && [ -x "run.sh" ]; then
  ./run.sh
else
  echo "脚本不存在或不可执行"
fi

🔢 数字相关判断

条件表达式

含义

示例

[ "$a" -eq "$b" ]

等于

[ "$x" -eq "100" ]

[ "$a" -ne "$b" ]

不等

[ "$x" -ne "0" ]

[ "$a" -gt "$b" ]

大于

[ "$age" -gt "18" ]

[ "$a" -lt "$b" ]

小于

[ "$score" -lt "60" ]

[ "$a" -ge "$b" ]

大于等于

[ "$num" -ge "10" ]

[ "$a" -le "$b" ]

小于等于

[ "$num" -le "100" ]

🔸 示例:

read -p "请输入年龄: " age
if [ "$age" -ge 18 ]; then
  echo "成年人"
else
  echo "未成年"
fi

🧠 小技巧:数值比较时不要用 [[ "$a" > "$b" ]]

那是 字符串字典序比较,不是数学意义上的大小比较,用 [ "$a" -gt "$b" ] 才是对的。

🧪 2.3.4 组合条件

可以使用逻辑运算符组合多个条件:

  • &&:与(and)
  • ||:或(or)
  • ! :非(not)

🔸 示例:

if [ -f "$file" ] && [ -r "$file" ]; then
  echo "文件存在且可读"
fi

🔁 2.3.5 [ ] 与 [[ ]] 判断区别

        这是一个非常经典也很容易混淆的点!我们来深入讲讲 [[ ... ]][ ... ] 的区别,简单总结 + 示例说明,让你一看就懂 👇


✅ 基本区别概览

比较项

[ ... ](test 命令)

[[ ... ]](bash 扩展)

是否为内建命令

否,调用的是 test命令

是 Bash 的关键字,执行效率更高

字符串比较支持

基础比较(=, !=)

支持模式匹配 ==, 通配符, 正则 =~

括号中是否可用 &&

是否支持正则

❌ 不支持

✅ 支持 =~ 正则匹配

是否需要变量加引号

建议加

可以不加,避免脚本崩溃

必须使用 #!/bin/bash 或其他兼容 Bash 的解释器,才能正常使用 [[ ... ]]


✅ 字符串比较
#!/bin/bash 
str="abc"

# 使用 []
if [ "$str" = "abc" ]; then
        echo "相等"
fi

# 使用 [[ ]] 
if [[ $str == abc ]]; then
        echo "相等"
fi

✔️ [[ ]] 中变量不加引号也不会出错;[ ] 中变量最好加引号,防止空值导致语法错误。


✅ 模式匹配
#!/bin/bash
filename="test.txt"

# [ ] 中不支持通配符匹配
# if [ "$filename" == *.txt ]; then  ❌ 错误

# [[ ]] 支持通配符匹配
if [[ $filename == *.txt ]]; then
  echo "是 txt 文件"
fi

✅ 正则匹配(只有 [[ ]] 支持)
email="user@example.com"

if [[ $email =~ ^[a-zA-Z0-9._%+-]+@[a-z]+\.[a-z]+$ ]]; then
  echo "邮箱合法"
fi

🔹 这个正则在 [ ] 里是完全无法用的。


✅ 逻辑运算符
a=5
b=10

# [ ] 不支持内部逻辑运算符,只能外部组合:
if [ $a -lt 10 ] && [ $b -gt 5 ]; then
  echo "满足条件"
fi

# [[ ]] 内部直接支持:
if [[ $a -lt 10 && $b -gt 5 ]]; then
  echo "满足条件"
fi

📌 总结一句话:

[ ] 是传统的 test 命令,兼容性强;[[ ]] 是 Bash 扩展,功能强大、安全性更高、语法更灵活。

必须使用 #!/bin/bash 或其他兼容 Bash 的解释器,才能正常使用 [[ ... ]]


2.4 shell 脚本循环语句的介绍

        Shell 中的循环语句主要有三种:for 循环、while 循环 和 until 循环。下面分别介绍这三种循环语句的基本用法和示例:


for 循环

语法形式一:遍历列表
for var in item1 item2 item3
do
  command
done

示例:

#!/bin/bash
for name in 张三 李四 王五
do
        echo " Hello, ${name} "
done

输出结果:

[toast@localhost shell-script]$ chmod u+x for-demo1.sh 
[toast@localhost shell-script]$ ./for-demo1.sh 
 Hello, 张三 
 Hello, 李四 
 Hello, 王五 
语法形式二:数值范围(Bash 特有)
for i in {1..5}
do
  echo "Number: $i"
done
语法形式三:C语言风格(适用于 bash)
for ((i=0; i<5; i++))
do
  echo "i=$i"
done

while 循环

语法:

while [ condition ]
do
  command
done

示例:

count=1
while [ $count -le 5 ] # 小于5
do
  echo "Count is $count"
  count=$((count + 1))
done

until 循环

语法:

until [ condition ]
do
  command
done

while 相反:while 是条件成立就执行;until 是条件不成立就执行。

示例:

count=1
until [ $count -gt 5 ]
do
  echo "Count is $count"
  count=$((count + 1))
done

跳出循环

break:跳出整个循环
for i in {1..10}
do
  if [ $i -eq 5 ]; then
    break
  fi
  echo $i
done
continue:跳过当前循环,继续下一次
for i in {1..5}
do
  if [ $i -eq 3 ]; then
    continue
  fi
  echo $i
done

2.5 shell 脚本方法定义的介绍

在 Shell 脚本中,方法(或函数) 是用来组织和重用代码的一个非常实用的结构。它可以让脚本更加模块化、可维护、易于调试。下面是对 Shell 脚本中方法(函数)的全面介绍:


🧩 1. Shell 函数的定义语法

function_name () {
  command1
  command2
  ...
}

或者:

function function_name {
  command1
  command2
  ...
}

推荐使用第一种 function_name () 的方式,它兼容性更好。


🛠 2. 示例

#!/bin/bash

say_hello() {
  echo "Hello, $1!"
}


say_hello "Alice" # say_hello 调用方法, "Alice" 传入参数

输出:

Hello, Alice!

📥 3. 传参方式

Shell 函数的参数用 $1, $2, ..., $@ 表示:

参数变量

含义说明

$0

脚本或函数的名称

$1

第一个参数

$2

第二个参数

$3

第三个参数

$#

传递给函数/脚本的参数个数

$@

"$1" "$2" ... 的形式展开所有参数

$*

"foo bar baz" 的形式展开所有参数

"$@"

每个参数独立展开(推荐写法)

"$*"

所有参数合并为一个字符串

$$

当前脚本的进程 PID

$?

上一个命令的退出状态码(0=成功,非0=失败)

#/bin/bash
add() {
  result=$(( $1 + $2 ))
  echo "Result: $result"
}

# 调用方法
add 3 5 # 最终结果等于 8


🔁 4. 返回值

Shell 函数不能直接返回字符串,只能通过 return 返回整数(0~255)作为状态码。要返回字符串,可以用 echo + 命令替换获取。

#!/bin/bash

# 返回状态码
check_file() {
  if [ -f "$1" ]; then
    return 0
  else
    return 1
  fi
}

check_file "/etc/passwd"
if [ $? -eq 0 ]; then
  echo "File exists"
else
  echo "File not found"
fi

或者用 echo 返回字符串:

#!/bin/bash
get_date() {
  echo "$(date +%F)"
}

today=$(get_date)
echo "Today is $today"

🧹 5. 本地变量 (local)

使用 local 声明变量仅在函数内部生效:

#!/bin/bash
greet() {
  local name=$1
  echo "Hi, $name"
}

🔁 6. 函数嵌套调用

函数可以调用其他函数:

#!/bin/bash
greet() {
  echo "Hello, $1"
}

run() {
  greet "$1"
}

run "Bob"

2.6 shell 对shell脚本 import 支持

在 Shell 脚本中虽然没有像 Python /Java 那样的 import 关键字,但它 支持通过 source.(点命令)来“引入”另一个脚本文件,起到类似 import 的作用。


🧩 Shell 脚本的“导入”语法

方式

语法示例

说明

source

source other_script.sh

读取并执行另一个脚本内容

.

. other_script.sh

等同于 source(更短)


📁 使用示例

👉 场景:你有两个脚本,一个是utils.sh 里面提供一个查看磁盘基本的使用情况,一个是main.sh 是主入口。

查看所在位置:

[toast@localhost shell-import]$ pwd
/home/toast/shell-script/shell-import
[toast@localhost shell-import]$ ll
total 8
-rwxr--r--. 1 toast toast 151 Apr 21 15:15 main.sh
-rwxr--r--. 1 toast toast 540 Apr 21 15:16 utils.sh
#!/bin/bash
# 文件名:utils.sh

# 显示磁盘空间的表格函数
show_disk_info() {
  echo "磁盘空间使用情况如下:"
  echo "--------------------------------------------"
  printf "%-20s %-10s %-10s %-10s %-10s\n" "挂载点" "总大小" "已用" "可用" "使用率"
  echo "--------------------------------------------"

  df -h --output=target,size,used,avail,pcent | tail -n +2 | while read mount size used avail usep; do
    printf "%-20s %-10s %-10s %-10s %-10s\n" "$mount" "$size" "$used" "$avail" "$usep"
  done
}
#!/bin/bash
# 文件名:main.sh

# 引入 utils.sh(相对路径,也可以写成绝对路径)
source ./utils.sh

# 调用函数
show_disk_info
[toast@localhost shell-import]$ ll
total 8
-rwxr--r--. 1 toast toast 151 Apr 21 15:15 main.sh
-rwxr--r--. 1 toast toast 540 Apr 21 15:16 utils.sh
[toast@localhost shell-import]$ ./main.sh 
磁盘空间使用情况如下:
--------------------------------------------
挂载点            总大小  已用     可用     使用率 
--------------------------------------------
/dev                 4.0M       0          4.0M       0%        
/dev/shm             1.8G       0          1.8G       0%        
/run                 732M       8.6M       724M       2%        
/                    45G        2.8G       43G        7%        
/boot                960M       225M       736M       24%       
/run/user/0          366M       0          366M       0%    


🔄 三、相对路径与绝对路径

使用 source 时最好用绝对路径或动态路径判断:

DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" #获取当前所在的绝对路径
source "$DIR/utils.sh"
[toast@localhost shell-import]$ echo "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
/home/toast/shell-script/shell-import
[toast@localhost shell-import]$ cd ~
[toast@localhost ~]$ echo "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
/home/toast
[toast@localhost ~]$ 

这样可确保无论从哪个目录运行主脚本都能正确找到依赖脚本。


📦 四、支持内容

使用 source 导入的脚本,可以包含:

  • 变量定义
  • 函数定义
  • 任何 Shell 命令
  • 甚至环境设置(比如 export)

⚠️ 五、注意事项

  1. source 是在当前 shell 中执行,所以引入的变量和函数会在当前脚本中直接生效;
  2. 被引入的脚本不能有 exit,否则会直接退出主脚本;
  3. 如果只想引入变量或函数,不要在被引入的脚本中写执行逻辑。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值