You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何检测被source的Bash脚本是否接收到传入参数?

解决Bash脚本source时参数混淆问题

问题背景

现有source.sh脚本内容如下:

echo "$#" "$@"

执行时存在两种无法区分的场景:

  • 继承shell参数场景:当前shell已通过set设置位置参数,直接source脚本
    $ set -- argument
    $ . ./source.sh
    1 argument
    
  • 传入source参数场景:source脚本时直接传入参数
    $ . ./source.sh argument
    1 argument
    

两种场景输出完全一致,无法判断参数是来自当前shell的位置参数,还是source脚本时主动传入的。

需求是让source.sh仅识别传给. source.sh的参数,同时支持直接执行(非source)的情况,期望实现以下输出:

$ set -- argument
$ . ./source.sh
0
$ . ./source.sh argument
1 argument
$ ./source.sh
0
$ ./source.sh argument
1 argument

解决方案

修改后的source.sh脚本如下:

#!/usr/bin/env bash

if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
    # 脚本被直接执行,直接使用当前的位置参数
    echo "$#" "$@"
else
    # 脚本被source,从Bash调用栈变量中提取source时传入的参数
    local arg_count=${BASH_ARGC[0]}
    local -a source_args=()
    
    # BASH_ARGV存储参数为逆序,倒序提取得到正确顺序
    for ((i=arg_count-1; i>=0; i--)); do
        source_args+=("${BASH_ARGV[i]}")
    done
    
    echo "$arg_count" "${source_args[@]}"
fi

原理说明

  • ${BASH_SOURCE[0]}:表示当前脚本的路径,${0}表示当前执行的进程名。当脚本被直接执行时,两者相等;当被source时,${0}是当前shell的进程名,与BASH_SOURCE[0]不等,以此区分执行方式。
  • BASH_ARGC:数组类型,存储每个调用帧的参数数量。脚本被source时,BASH_ARGC[0]就是source操作传入的参数个数,不受当前shell位置参数影响。
  • BASH_ARGV:数组类型,存储所有调用栈的参数,但以逆序排列。因此需要倒序提取BASH_ARGV中对应数量的元素,得到source时传入参数的正确顺序。

内容的提问来源于stack exchange,提问作者KamilCuk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 04:02:04