在耦合的shell脚本之间干净地传递选项

时间:2014-01-28 12:53:36

标签: bash shell getopts tightly-coupled-code

我有一个(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[@]},并传递给{{ 1}}。

现在我在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=("$@") 的{​​{1}}个$OPTIND条目作为$allOpts传递给[OPTIONS]。但这似乎过于复杂,而且,它需要将<{1}}的有效选项列表复制,这是一个管理噩梦。

我还可以创建一个新脚本,专门用于解析这些选项。但这似乎有点尴尬,因为它在myBaseScript.sh中创建了依赖,而以前就不存在......

那么,最简​​洁的方法是什么?

2 个答案:

答案 0 :(得分:2)

如果您使用mySuperScript.sh和目录列表之间的附加标记来呼叫[OPTIONS]

mySuperScript.sh [OPTIONS] -- DIR1 [DIR2 ...]

然后,您可以遍历参数并将选项集合到变量中。类似的东西:

while [ "$1" -ne "--" ]; do
  OPTIONS="$OPTIONS $1"
  shift
done
shift

然后您可以稍后致电:

myBaseScript.sh $OPTIONS $some_list_of_files

只要您不尝试处理包含空格的可选参数,这就可以正常工作。

更实际的是,这通常是在我开始研究Python时。

答案 1 :(得分:2)

我不知道您的整个用例,但如果您的目标只是支持文件和目录,那么您可以使用单个脚本来检查参数是否是目录并对其进行爬网。

例如:

#!/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[@]}"