将命令行选项传递给 bash 中调用的脚本

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18965305/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 06:39:42  来源:igfitidea点击:

Passing command line options to invoked script in bash

bashshellcommand-line-arguments

提问by Michael

Suppose I have a script a.shto be invoked with options

假设我有一个a.sh要使用选项调用的脚本

a.sh -a1 a1option -a2 a2option

Suppose also I have a script b.sh, which invokes a.shand uses its own options. So user executes the scripts as follows:

假设我还有一个 script b.sh,它调用a.sh并使用自己的选项。所以用户执行脚本如下:

b.sh -b1 b1option -b2 b2option -a1 a1option -a2 a2option

Now I wonder how to parse the command line options in b.sh.

现在我想知道如何解析b.sh.

I do not need to parse the entirecommand line. I do not want b.shto be aware of options a1and a2. I would like to get only options b1and b2and pass the restto a.sh.

我不需要解析整个命令行。我不想b.sh知道选项a1a2. 我只想获得选项b1b2并将其余部分传递给a.sh.

How would you do it ?

你会怎么做?

回答by dangenet

As requested, this method avoids parsing the entire command line. Only the arguments up to --are collected for b.sh. Then the arguments for b are stripped and only the remaining arguments are passed to a.sh.

根据要求,此方法避免解析整个命令行。只--收集 到的参数b.sh。然后去除 b 的参数,只将剩余的参数传递给a.sh

b.shis invoked with b.sh -b b1option -B b2option -- -a1 a1option -a2 a2option. In this line, the double dash --indicates the end of options for b.sh. The following parses the options before the --for use by b.sh, then removes the b arguments from the $@so you can pass it to a.shwithout worrying about what errors a.shmight give you.

b.sh用 调用b.sh -b b1option -B b2option -- -a1 a1option -a2 a2option。在这一行中,双破折号--表示 的选项结束b.sh。下面解析--for use by之前的选项b.sh,然后从 the 中删除 b 参数,$@以便您可以将其传递给,a.sh而不必担心a.sh可能会给您带来什么错误。

while getopts ":b:B:" opt; do
    case $opt in
        b) B1=${OPTARG}
        ;;
        B) B2=${OPTARG}
        ;;
    esac 
done
## strips off the b options (which must be placed before the --)
shift $(({OPTIND}-1))
a.sh "$@"

A note: This method utilizes the bash builtin getopts. Getopts (as opposed to getopt, no s) takes only single-character options; hence, I have used band Binstead of b1and b2.

注意:此方法使用 bash 内置的 getopts。Getopts(与 getopt 相对,没有 s)只接受单字符选项;因此,我使用了bandB而不是b1and b2

My favorite getoptsreference.

我最喜欢的getopts参考。

回答by konsolebox

You can do something like this:

你可以这样做:

#!/bin/bash

while [[ $# -gt 0 ]]; do
    case "" in
    -b1)
        B1=true
        B1OPT=
        shift
        ;;
    -b2)
        B2=true
        B2OPT=
        shift
        ;;
    --)
        shift
        break
        ;;
    *)
        echo "Invalid option: "
        exit 1  ## Could be optional.
        ;;
    esac
    shift
done

bash a2.sh "$@"

Note that you should place your variable $@inside doublequotes to prevent word splitting when expanded.

请注意,您应该将变量$@放在双引号内,以防止展开时分词。

回答by danadam

If a.sh can ignore options it doesn't know you can just call it with all the options b.sh was called:

如果 a.sh 可以忽略选项,它不知道您可以使用 b.sh 调用的所有选项调用它:

a.sh "${@}"