如何在Bash的case语句中传递函数参数?报错信息无法显示问题
问题原因
你遇到的核心问题是管道|的子shell隔离特性:当你用error_mess='xxx' | usage时,管道两侧的命令会在两个独立的子shell中执行。error_mess变量是在左侧子shell里定义的,右侧的usage函数所在的子shell根本访问不到这个变量,所以自然打印不出错误信息。
修正方案
有两种简单的修复方式,根据你的场景选择:
方案1:去掉管道,用分号分隔命令
直接在同一个shell环境里先赋值变量,再调用usage函数,这样变量就能被函数读取到:
usage() { if [ -n "$error_mess" ]; then echo -e "$error_mess"; fi; echo -e "usage statement too long to present" 1>&2; exit 1; } while getopts ":f:" flag do case "${flag}" in f) if [ -n "${OPTARG}" ] ; then file=${OPTARG} ; else error_mess='\033[1m\033[5mError: file cannot be empty\033[0m'; usage; fi;; *) usage;; esac done
方案2:让usage函数接受参数(更推荐)
依赖全局变量容易引发意外问题,不如直接把错误信息作为参数传给usage,这样不同场景可以灵活传参或者不传:
# 重新定义usage,接受可选的错误信息参数 usage() { # 如果有传入参数,就打印错误信息 if [ -n "$1" ]; then echo -e "$1" >&2 fi # 打印固定的usage说明 echo -e "usage statement too long to present" >&2 exit 1 } while getopts ":f:" flag do case "${flag}" in f) if [ -n "${OPTARG}" ] ; then file=${OPTARG} ; else # 直接把错误信息作为参数传给usage usage '\033[1m\033[5mError: file cannot be empty\033[0m'; fi;; *) # 不需要错误信息时直接调用 usage;; esac done
这种方式更健壮,也符合Shell函数的最佳实践,避免了全局变量的依赖。
内容的提问来源于stack exchange,提问作者jimmymcheung
相关产品推荐
相关产品推荐

