Linux Shell 脚本教程 第 9 篇 位置参数变量详解(详细版)

Shell 脚本中有一类特别重要的变量——位置参数变量。它们以 $ 开头,专门用来接收和处理传给脚本的参数、命令执行状态、脚本自身信息等。在写 Shell 脚本时,正确理解和使用这些变量,是掌握脚本编程的基础。

在正式内容开始之前,我先给大家再次介绍一下shell脚本的执行吧,相信很多人不懂,其实我在开始写shell文章的时候已经说过了,但是讲的可能不是很细致,今天写这篇文章,我觉得有必要再次讲解一下了。

脚本开头的 shebang(如 #!/bin/bash)有什么用?
shell脚本执行的方式有哪些,区别在哪里?
什么是子 Shell 和当前 Shell?
来看这两篇文章,如果你真的在好好且系统的学习shell,听话,在开始学习下面内容之前,请先阅读,我之前的文章,中国人不骗中国人

什么是位置参数变量?

位置参数变量是 Shell 中用来获取脚本运行时传入参数和状态信息的特殊变量,能够让脚本更加灵活和智能。

变量含义
$0当前脚本的名称(包含路径)
$1 ~ $9脚本执行时传入的第 1 至第 9 个参数
${10}第 10 个及以后参数,必须用花括号包裹
$#传入参数的数量
$@传入的所有参数,作为独立的字符串列表处理(推荐遍历参数用)
$*传入的所有参数,作为一个整体字符串处理
$?上一条命令的退出状态码,0 表示成功,非 0 表示失败
$$当前 Shell 脚本进程的 PID
$!最近一次后台命令的进程号

$0 — 当前脚本名

$0 代表当前执行的脚本文件名,可以是绝对路径或相对路径。

问题来了?什么时候代表的绝对路径,什么时候代表的是相对路径

好~,这就需要,看你如何执行的脚本了,运行时使用的是相对路径,那么$0就代表的是相对路径,运行时使用的是绝对路径那么代表的就是绝对路径

#!/bin/bash
echo "当前脚本名称是:$0"

还有一个问题就是:通过 source shell .sh或者是. shell.sh执行,则 $0 bash 或 -bash;如果是软链接调用,则显示的是软链接名


来看,这也就是为什么我在写这篇文章之前,要重点写上一篇文章了

  • $0是 当前 shell 进程的名称。
  • 当你运行一个脚本(如 bash script.sh 或 ./script.sh),Bash 会启动一个新的子 shell 来执行这个脚本,此时$0就是这个脚本文件名。
  • 如果你使用的是 source script.sh 或 . script.sh,不会创建新的 shell 进程,而是直接在当前 shell 中“加载”并执行该脚本。

教你几种方法,无论是使用那种方式执行脚本,都只输出脚本名称

  1. BASH_SOURCE 变量
    • 它是 Bash 内置变量数组,记录了调用栈中各个脚本文件的名字。
表达式含义说明
${BASH_SOURCE[0]}当前正在执行的脚本路径最常用,用于获取自己是谁
${BASH_SOURCE[1]}调用当前脚本的上级脚本路径可以用来做日志追踪、调试
${BASH_SOURCE[@]}整个调用栈数组(逐个元素)遍历或打印多个层级时有用
${BASH_SOURCE[*]}整个调用栈合并为一个字符串方便记录日志、调试输出


#!/bin/bash
echo "当前脚本名称: ${BASH_SOURCE[0]}"

  1. basename 工具
    • 是一个 标准的Linux/Unix命令行工具,用于:从一个文件路径中提取出“文件名”部分(即去掉目录路径)。
#!/bin/bash
SHELL_NAME=$(basename "$0")
echo "当前脚本名称: $SHELL_NAME"

  1. 还有一些标准的Linux/Unix命令行工具,例如 readlink 、 dirname 等。

这些命令工具大家可以下去了解一下,如果需要,我找个时间再把这些工具讲一下,评论区给我留言

$1 ~ $9 — 第1到第9个参数

这些变量依次对应脚本后面传入的参数。直接讲示例

#!/bin/bash
echo "第一个参数是:$1"
echo "第二个参数是:$2"
echo "第三个参数是:$3"

${10}${11}……超过9个参数

超过9个参数时,必须使用花括号,否则 $10 会被解析为 $1 + 0

#!/bin/bash
echo "第十个参数是:${10}"
echo "第十一参数是:${11}"

这里有一个主意事项哦。如果你传入的第10个参数是10,执行调用$10也会正常的输出,这个是假象哦~,自己去琢磨一下为什么

$# — 参数个数

这个变量表示传入脚本的参数总数。

#!/bin/bash
echo "一共传入了 $# 个参数"

$@$* 的区别及用法

这两个变量都代表所有参数,但处理方式不同:

  • $@:将每个参数视为独立的字符串。通常在双引号中用来遍历参数,能保持带空格参数的完整性。
  • $*:将所有参数当作一个整体字符串,用第一个字符(默认为空格)分隔。
    注意:调用$@$*的时候必须要用 "" (双引号)
#!/bin/bash
echo "用 \"\$@\" 遍历参数:"
for arg in "$@"; do
    echo "参数:$arg"
done

echo "用 \"\$*\" 遍历参数:"
for arg in "$*"; do
    echo "参数:$arg"
done

💡 建议: 在循环遍历参数时,优先使用 "$@",因为它能正确处理包含空格的参数,避免错误拆分。


$? — 上一条命令的退出状态

执行命令后,用 $? 获取其退出状态。返回值 0 表示成功,非 0 表示失败。

#!/bin/bash
ls /test
echo "命令返回状态:$?"

ls -la /data/shell
echo "命令返回状态:$?"

$$ — 当前脚本进程 PID

显示当前脚本运行的进程号,有时用于生成临时文件名等。这个在上一篇文章中已经多次运用了,可以看下

#!/bin/bash
echo "当前脚本进程号是:$$"

$! — 最近后台命令的 PID

当脚本中执行后台任务(用 & 结尾)时,$! 会返回该后台进程号。

#!/bin/bash
sleep 60 &
echo "后台进程的 PID 是:$!"

综合示范脚本

#!/bin/bash
# 定义 ANSI 颜色代码
RED='\033[0;31m'     # 红色
GREEN='\033[0;32m'   # 绿色
YELLOW='\033[0;33m'  # 黄色
BLUE='\033[0;34m'    # 蓝色
PURPLE='\033[0;35m'  # 紫色
CYAN='\033[0;36m'    # 青色
NC='\033[0m'         # 无颜色 (No Color)
# ===============================
#  Shell 特殊变量演示脚本
#  包含 $0, $1-$9, ${10}, ${11}
#       $# "$@" "$*" $? $$ $!
# ===============================
# 每个标题使用不同颜色显示
echo -e "${RED}===== 脚本执行信息 =====${NC}"
echo -e "脚本名(\$0): $0"
echo -e "${GREEN}传入参数个数(\$#): $#${NC}"
echo -e "${YELLOW}=== 参数 \$1 ~ \$9 ===${NC}"
for i in {1..9}; do
    eval "val=\$$i"
    echo "参数 \$${i}: ${val:-未提供}"
done

echo -e "${BLUE}=== 参数 \${10} 和 \${11} ===${NC}"
echo "第10个参数(\${10}): ${10:-未提供}"
echo "第11个参数(\${11}): ${11:-未提供}"
echo -e "${PURPLE}=== 所有参数列表(\"\$@\") ===${NC}"
index=1
for param in "$@"; do
    echo "参数 \$${index}: $param"
    ((index++))
done

echo -e "${CYAN}=== 所有参数合并(\"\$*\") ===${NC}"
echo "\"\$*\": $*"
echo -e "${RED}=== 当前脚本进程号(\$\$) ===${NC}"
echo "当前进程 PID(\$\$): $$"
echo -e "${GREEN}=== 测试命令失败状态码(\$?) ===${NC}"
echo "尝试访问不存在的目录 /notexist:"
ls /notexist
echo "上一个命令的状态码(\$?): $?"
echo -e "${YELLOW}=== 后台执行 sleep 命令,并获取其 PID(\$!) ===${NC}"
sleep 30 &
echo "后台执行的 sleep 命令 PID 是(\$!): $!"
echo -e "${NC}\n✅ 脚本执行完毕,请注意观察不同变量的行为!"

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

安全日记pro

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

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

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

打赏作者

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

抵扣说明:

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

余额充值