如何创建一个带参数的bash脚本?

A Q*_*ker 18 bash

我已经知道了getopts,这很好,但令人讨厌的是你必须有一个标志,即使是强制性的参数.

理想情况下,我希望能够拥有一个以这种形式接收参数的脚本:

script.sh [optional arguments] [anything required]
Run Code Online (Sandbox Code Playgroud)

例如

script.sh -rvx output_file.txt
Run Code Online (Sandbox Code Playgroud)

脚本说你必须有一个输出文件.有没有简单的方法来做到这一点?

据我所知,使用getopts它必须看起来像:script.sh -rvx -f output_file.txt,这不是很干净.

如果有必要,我也可以使用python,但只有2.4可用,这有点过时了.

Sor*_*gal 29

不要使用内置的getopts,而是使用getopt(1).它们(巧妙地)是不同的,并且做得很好.对于您的情况,您可以这样做:

#!/bin/bash

eval set -- $(getopt -n $0 -o "-rvxl:" -- "$@")

declare r v x l
declare -a files
while [ $# -gt 0 ] ; do
        case "$1" in
                -r) r=1 ; shift ;;
                -v) v=1 ; shift ;;
                -x) x=1 ; shift ;;
                -l) shift ; l="$1" ; shift ;;
                --) shift ;;
                -*) echo "bad option '$1'" ; exit 1 ;;
                *) files=("${files[@]}" "$1") ; shift ;;
         esac
done

if [ ${#files} -eq 0 ] ; then
        echo output file required
        exit 1
fi

[ ! -z "$r" ] && echo "r on"
[ ! -z "$v" ] && echo "v on"
[ ! -z "$x" ] && echo "x on"

[ ! -z "$l" ] && echo "l == $l"

echo "output file(s): ${files[@]}"
Run Code Online (Sandbox Code Playgroud)

编辑:为了完整性,我提供了一个处理需要参数的选项的例子.

  • @A问题Asker:请注意某些版本的`getopt`存在问题.从`man`页面:"getopt(1)的传统实现无法处理参数和非选项参数中的空格和其他(特定于shell)特殊字符." 有关详细信息,请参阅[`man`页面](http://linux.die.net/man/1/getopt)以及测试您的版本是否存在这些问题的方法. (3认同)

fra*_*nkc 11

如果您使用的是getops,请$OPTIND-1在您的案例陈述之后转换.然后剩下的$*将是其他一切,这可能是你想要的.

shift $(( ${OPTIND} - 1 )); echo "${*}"
Run Code Online (Sandbox Code Playgroud)