如何在调用两个Bash子程序的主程序中为各子程序使用getopts
问题描述
我有一个主程序A,以及两个子程序B和C。程序A用于运行另外两个程序并显示帮助选项,B和C是调用C语言程序的Bash脚本。程序A的基础代码如下:
while getopts "hv" option; do case ${option} in h) # Call the Help function Help exit;; v) # Call the Version function Version exit;; \?) # Invalid option echo "Invalid option. Use flag -h for help." exit;; esac done if [ "$1" = "B" ] ; then source <path_to>/B.sh fi if [ "$1" = "C" ] ; then source <path_to>/C.sh fi
我的问题是:能否以主程序A为入口,在执行子程序B时使用其专属的getopts选项,执行子程序C时使用另一组专属选项?例如,若-p是子程序B调用的程序所需的线程数参数,能否通过A B -p 10这样的命令实现参数传递?
解决方案
完全可以实现,核心思路是让主程序A先处理自身的全局选项(-h/-v),然后将剩余的参数(子命令+子命令专属参数)传递给对应的子程序,由子程序自行解析专属选项。具体修改如下:
1. 修改主程序A的代码
调整主程序逻辑,在处理完全局选项后移除已处理的参数,再识别子命令并传递剩余参数:
# 处理主程序自身的全局选项 while getopts "hv" option; do case ${option} in h) Help exit 0 ;; v) Version exit 0 ;; \?) echo "Invalid option. Use flag -h for help." >&2 exit 1 ;; esac done # 移除已处理的全局选项参数,让$1指向子命令(B/C) shift $((OPTIND - 1)) # 识别子命令并传递剩余参数 if [ "$1" = "B" ]; then # 移除子命令B,将剩余参数传递给B.sh shift source <path_to>/B.sh "$@" elif [ "$1" = "C" ]; then # 移除子命令C,将剩余参数传递给C.sh shift source <path_to>/C.sh "$@" else echo "Unknown subcommand: $1. Use -h for help." >&2 exit 1 fi
2. 调整子程序B.sh的代码
让B.sh自行处理专属选项,例如解析-p参数:
# B.sh的参数解析逻辑 THREADS=4 # 默认线程数 while getopts "p:" option; do case ${option} in p) THREADS="$OPTARG" ;; \?) echo "B: Invalid option. Use -h for help." >&2 exit 1 ;; :) echo "B: Option -$OPTARG requires an argument." >&2 exit 1 ;; esac done # 移除已处理的选项参数,剩下的可以传给后续的C程序 shift $((OPTIND - 1)) # 调用C语言程序,传递线程数和剩余参数 /path/to/your/c_program_b -t "$THREADS" "$@"
3. 子程序C.sh同理
按照B.sh的模式,编写C专属的选项解析逻辑,比如处理它自己的参数(例如-f指定输入文件等)。
效果验证
执行A B -p 10时,主程序A会先处理全局选项(这里无全局选项),然后将-p 10传递给B.sh,B.sh解析出线程数为10后,再传递给对应的C语言程序,完全符合需求。
内容的提问来源于stack exchange,提问作者Arturo
相关产品推荐
相关产品推荐

