8wDlpd.png
8wDFp9.png
8wDEOx.png
8wDMfH.png
8wDKte.png

如何解析 Bash 中的命令行参数?

YMK 1月前

133 0

假设我有一个用以下行调用的脚本:./myscript -vfd ./foo/bar/someFile -o /fizz/someOtherFile 或者这个:./myscript -v -f -d -o /fizz/someOtherFile ./foo/bar/someFile 什么是...

假设我有一个用以下行调用的脚本:

./myscript -vfd ./foo/bar/someFile -o /fizz/someOtherFile

或者这个:

./myscript -v -f -d -o /fizz/someOtherFile ./foo/bar/someFile 

解析此问题的一种可接受的方式是什么,使得在每种情况下(或两者的某种组合) $v , $f ,和 $d 都将被设置为 true 并且 $outFile 等于 /fizz/someOtherFile

帖子版权声明 1、本帖标题:如何解析 Bash 中的命令行参数?
    本站网址:http://xjnalaquan.com/
2、本网站的资源部分来源于网络,如有侵权,请联系站长进行删除处理。
3、会员发帖仅代表会员个人观点,并不代表本站赞同其观点和对其真实性负责。
4、本站一律禁止以任何方式发布或转载任何违法的相关信息,访客发现请向站长举报
5、站长邮箱:yeweds@126.com 除非注明,本帖由YMK在本站《shell》版块原创发布, 转载请注明出处!
最新回复 (0)
  • No answer showcases enhanced getopt . And the top-voted answer is misleading: 它要么忽略 -⁠vfd 样式短选项(由OP要求),要么忽略位置参数后的选项(也是由OP要求);并且它忽略了解析错误。 相反:

    • Use enhanced getopt from util-linux or formerly GNU glibc .1
    • GNU glibc 的 C 函数 getopt_long() 一起工作
    • 此页上没有其他解决方案可以做到这一切
      • handles spaces, quoting characters and even binary in arguments 2 (non-enhanced getopt can’t do this)
      • it can handle options at the end: script.sh -o outFile file1 file2 -v ( getopts doesn’t do this)
      • allows = -style long options: script.sh --outfile=fileOut --infile fileIn (allowing both is lengthy if self parsing)
      • allows combined short options, e.g. -vfd (real work if self parsing)
      • allows touching option-arguments, e.g. -oOutfile or -vfdoOutfile
    • 已经很老了3,它 预装 在任何 GNU 系统上(主要是 Linux);见脚注1
    • 您可以使用以下方法测试它的存在: getopt --test →返回值 4。
    • 其他 getopt 或 shell 内置的 getopts 用途有限。

    以下调用

    myscript -vfd ./foo/bar/someFile -o /fizz/someOtherFile
    myscript -v -f -d -o/fizz/someOtherFile -- ./foo/bar/someFile
    myscript --verbose --force --debug ./foo/bar/someFile -o/fizz/someOtherFile
    myscript --output=/fizz/someOtherFile ./foo/bar/someFile -vfd
    myscript ./foo/bar/someFile -df -v --output /fizz/someOtherFile
    

    全部返回

    verbose: y, force: y, debug: y, in: ./foo/bar/someFile, out: /fizz/someOtherFile
    

    以下内容 myscript

    #!/bin/bash
    # More safety, by turning some bugs into errors.
    set -o errexit -o pipefail -o noclobber -o nounset
    
    # ignore errexit with `&& true`
    getopt --test > /dev/null && true
    if [[ $? -ne 4 ]]; then
        echo 'I’m sorry, `getopt --test` failed in this environment.'
        exit 1
    fi
    
    # option --output/-o requires 1 argument
    LONGOPTS=debug,force,output:,verbose
    OPTIONS=dfo:v
    
    # -temporarily store output to be able to check for errors
    # -activate quoting/enhanced mode (e.g. by writing out “--options”)
    # -pass arguments only via   -- "$@"   to separate them correctly
    # -if getopt fails, it complains itself to stdout
    PARSED=$(getopt --options=$OPTIONS --longoptions=$LONGOPTS --name "$0" -- "$@") || exit 2
    # read getopt’s output this way to handle the quoting right:
    eval set -- "$PARSED"
    
    d=n f=n v=n outFile=-
    # now enjoy the options in order and nicely split until we see --
    while true; do
        case "$1" in
            -d|--debug)
                d=y
                shift
                ;;
            -f|--force)
                f=y
                shift
                ;;
            -v|--verbose)
                v=y
                shift
                ;;
            -o|--output)
                outFile="$2"
                shift 2
                ;;
            --)
                shift
                break
                ;;
            *)
                echo "Programming error"
                exit 3
                ;;
        esac
    done
    
    # handle non-option arguments
    if [[ $# -ne 1 ]]; then
        echo "$0: A single input file is required."
        exit 4
    fi
    
    echo "verbose: $v, force: $f, debug: $d, in: $1, out: $outFile"
    

    1增强型 getopt 适用于大多数“bash 系统”,包括 Cygwin;在 OS X 上尝试 brew install gnu-getopt , brew install util-linux or sudo port install getopt
    2POSIX exec() 约定没有可靠的方法在命令行参数中传递二进制 NULL;这些字节过早地结束了参数
    3第一个版本于 1997 年或之前发布(我只追溯到 1997 年)

返回
作者最近主题: