我有一个(bash)shell脚本myBaseScript.sh
,具有以下签名:
myBaseScript.sh [OPTIONS] FILE1 [FILE2 ...]
此脚本myBaseScript.sh
通过getopts
解析选项,如下所示:
while getopts ":hi:m:s:t:v:" opt; do
#...
done
shift $(($OPTIND-1))
FILES=("$@")
现在我希望创建一个脚本mySuperScript.sh
,它调用myBaseScript.sh
,允许将选项转发到基本脚本:
mySuperScript.sh [OPTIONS] DIR1 [DIR2 ...]
其中[OPTIONS]
是myBaseScript.sh
中使用的选项;它们不在mySuperScript.sh
中使用。
脚本mySuperScript.sh
是爬过所有目录DIR1
、[DIR2]
等,编制一个有效文件列表${FILES[@]}
,传递给myBaseScript.sh
。
现在我在mySuperScript.sh
有这个:
myBaseScript.sh "$@" "${FILES[@]}"
其中${FILES[@]}
是当前路径中的文件列表。换句话说,这允许
mySuperScript.sh [OPTIONS]
但不适用于任何可选的DIR1
、[DIR2]
等。
我可以使用
allOpts=("$@")
while getopts ":hi:m:s:t:v:" opt; do echo. > /dev/null; done
shift $(($OPTIND-1))
DIRS=("$@")
然后将$allOpts
的前$OPTIND
个条目作为[OPTIONS]
传递给myBaseScript.sh
。但这似乎过于复杂,而且,它需要复制有效选项列表才能myBaseScript.sh
,这是一场管理噩梦。
我还可以创建一个新脚本,专门用于解析这些选项。但这似乎也有点尴尬,因为它在myBaseScript.sh
中产生了以前不存在的依赖关系......
那么,最干净的方法是什么?
我不知道你的整个用例,但如果你的目标只是同时支持文件和目录,那么你可以使用一个脚本来检查参数是否是一个目录并爬网它。
例如:
#!/bin/bash
crawl_dir() {
dir="$1"
find "$dir" -type f
}
# parse options
while getopts ":hi:m:s:t:v:" opt; do
echo ...
done
shift $(($OPTIND-1))
args=( "$@" )
# parse arguments
files=()
for arg in "${args[@]}"
do
if [[ -d "$arg" ]]
then
files+=( $(crawl_dir "$arg") )
else
files+="$arg"
fi
done
# now you have an array of files to process
process "${files[@]}"
如果在[OPTIONS]
和目录列表之间使用附加标记调用mySuperScript.sh
:
mySuperScript.sh [OPTIONS] -- DIR1 [DIR2 ...]
然后,您可以迭代参数并将选项收集到变量中。 像这样:
while [ "$1" -ne "--" ]; do
OPTIONS="$OPTIONS $1"
shift
done
shift
然后,您可以稍后呼叫:
myBaseScript.sh $OPTIONS $some_list_of_files
只要您不尝试处理包含空格的可选参数,这就可以正常工作。
在更实际的笔记中,这通常是我开始研究Python的时候。