1

我有一个 (bash) shell script 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[@]}"

where${FILES[@]}当前路径中的文件列表。换句话说,这允许

mySuperScript.sh [OPTIONS] 

但不适用于任何可选DIR1的 ,[DIR2]等。

我可以使用

allOpts=("$@")
while getopts ":hi:m:s:t:v:" opt; do echo. > /dev/null; done
shift $(($OPTIND-1))    
DIRS=("$@")

然后传递as to的第一个$OPTIND条目。但这似乎过于复杂,而且需要将有效选项列表复制到,这是管理上的噩梦。$allOpts[OPTIONS]myBaseScript.shmyBaseScript.sh

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

那么,最干净的方法是什么?

4

2 回答 2

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 的时候。

于 2014-01-28T13:31:19.787 回答
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[@]}"
于 2014-01-28T13:46:51.443 回答