脚本接受参数和选项,类似于命令

脚本接受参数和选项,类似于命令

我想编写一个用作命令的 bash 脚本,它应该接受选项以及不带任何选项的参数。我能够使用 getops 编写接受选项的脚本,但无法为脚本提供不带选项的参数。

下面的例子运行良好

myscript -f filename  

但是如果我不提供任何选项,相同的脚本也应该可以工作。

myscript username

答案1

#!/bin/bash
fname="/default"
while getopts f: arg ; do case $arg in
        f)      fname="$OPTARG";;
        :)      echo"${0##*/}: Must supply an argument to $OPTARG."
                exit 1
                ;;
        \?)     echo "Invalid option. Abort"
                exit 1
                ;;
        esac
        done
shift $(($OPTIND - 1))

# Demonstration
echo "fname=$fname"    
echo "There are $# remaining arguments: $*"

例子:

$ myscript -f newfile
fname=newfile
There are 0 remaining arguments: 

$ myscript arg1 arg2
fname=/default
There are 2 remaining arguments: arg1 arg2

$ myscript -f newfile arg1 arg2
fname=newfile
There are 2 remaining arguments: arg1 arg2

答案2

我知道您特别提到getopts,但另一种选择是通过循环来循环遍历while参数"$*"

file=""
user=""
other_args=""
while [ "$*" != "" ]; do
    case $1 in 
        "-f")
            file="$2"
            shift
        ;;
        "-u")
            user="$2"
            shift
        ;;
        "--help"|"help"|"-?")
            echo "usage: script.sh -f [file] -u [user] [other_args]"
            break
        ;;
        *) other_args="${other_args} $1" ;;
    esac
    shift
done
echo "file=${file}, user=${user}, other_args=${other_args}"

以下是脚本中其用法(以及其他一些内容)的一个例子a_pirate_says.sh

#!/bin/sh

me_file="tortuga"
me_crew="scallywags"
me_other_args=""

usage()
{
    echo "usage: a_pirate_says.sh [arg] [arg] [arg]"
    echo "       arg        An ARRRggument"
    echo "       arg        Another AARrrrrgument"
    echo "       arg        Pirates love AARRrrrrgumengs"
}

check_me_args()
{
    if [ "$#" -eq 0 ]; then return 3; fi
    me_return=0
    while [ "$*" != "" ]; do
        case $1 in 
            "-f") # we be specifically wanting me_file changed
                me_file="$2"
                shift
                ;;
            "-c") # we be specifically wanting me_crew changed
                me_crew="$2"
                shift
                ;;
            "yo")
                if [ "$2" == "ho" ]; then
                    shift
                    if [ "$3" == "ho" ]; then
                        shift
                        echo "and a bottle of rum!"
                    else
                        echo "yo ho, a pirates life for me"
                    fi
                else
                    echo "gabba gabba .. wait..."
                fi
                ;;
            "dead man tell no tales") echo "and live men tell no truth" ;;
            "valar morghulis")        echo "valar dohaeris" ;;
            "help")                   me_return=1 ;;
            "--help"|"-?") # ye specify multiple AArrrrgg's with the handy pipe
                echo "Ye must really be needin help .."
                usage
                me_return=2
                break
                ;;
            *) me_other_args="${me_other_args} $1" ;;
        esac
        shift
    done
    return $me_return
}

# we be passin' the quoted "$@" so we be enabling the
# check_me_args function to handle passed in quotes
check_me_args "$@"
ye_return=$? # what say ye check_me_args????

if [ ! $ye_return -eq 0 ]; then
    echo "To bad ${me_crew}! Weigh anchor we head out in a fortnight for ${me_file} .."
    if [ "${me_other_args}" != "" ]; then
        echo "If ye be disagreeing with my command, then to ye I say ${me_other_args}!!!!!"
    fi
    case $ye_return in
        2) ;; # a true cry for help matty, we shall ignore this return value, aye!
        1) echo "A true pirate ne'er asks for help .. they DEMANDS it!" ;;
        3) echo "Ye did not put words upon the command line, I'm acquiesced to disincline your request" ;;
        *) echo "BELAY THAT!" ;;
    esac
    exit 1
fi

echo "Welcome ${me_crew}! We be hoisting our sails to ${me_file} .."
if [ "${me_other_args}" != "" ]; then
    echo "If ye be disagreeing with my command, then to ye I say ${me_other_args}!!!!!"
fi

如果您愿意的话,这只是处理 shell 参数的另一种方法。

希望有所帮助。

相关内容