bash:在所有参数之后存储所有命令行参数

时间:2010-06-24 01:47:34

标签: bash

我如何创建这个小脚本?

例如:

~$ script.sh -b my small string... other things -a other string -c any other string ant etc

我只想要字符串,每个人都有一个模式。

-b
my small string... other things
-a
other string
-c
any other string ant etc

任何人都知道如何实现它?

由于

3 个答案:

答案 0 :(得分:6)

这是一个非常简单的命令行参数循环。命令行参数为$1$2等,命令行参数的数量为$#。在我们完成这些参数后,shift命令会丢弃这些参数。

#!/bin/bash

while [[ $# -gt 0 ]]; do
    case "$1" in
        -a) echo "option $1, argument: $2"; shift 2;;
        -b) echo "option $1, argument: $2"; shift 2;;
        -c) echo "option $1, argument: $2"; shift 2;;
        -*) echo "unknown option: $1"; shift;;
        *)  echo "$1"; shift;;
    esac
done

UNIX命令通常希望您自己引用多字参数,以便它们显示为单个参数。用法如下:

~$ script.sh -b 'my small string... other things' -a 'other string' -c 'any other string ant etc'
option -b, argument: my small string... other things
option -a, argument: other string
option -c, argument: any other string ant etc

请注意我是如何引用长篇论词的。

我不推荐它,但是如果你真的想在命令行中传递多个单词但是将它们视为单个参数,那么你需要更复杂的东西:

#!/bin/bash

while [[ $# -gt 0 ]]; do
    case "$1" in
        -a) echo "option: $1"; shift;;
        -b) echo "option: $1"; shift;;
        -c) echo "option: $1"; shift;;

        -*) echo "unknown option: $1"; shift;;

        *)  # Concatenate arguments until we find the next `-x' option.
            OTHER=()

            while [[ $# -gt 0 && ! ( $1 =~ ^- ) ]]; do
                OTHER+=("$1")
                shift
            done

            echo "${OTHER[@]}"
    esac
done

使用示例:

~$ script.sh -b my small string... other things -a other string -c any other string ant etc
option: -b
my small string... other things
option: -a
other string
option: -c
any other string ant etc

但是,不建议使用此用法。它违背了UNIX规范和约定来连接像这样的参数。

答案 1 :(得分:0)

我考虑用getopt来做这件事,但我不认为它有能力;将一个不带引号的间隔字符串视为一个参数是非常不寻常的。我想你将不得不手动完成它;例如:

long_str=""
for i; do
    if [ ${i:0:1} = '-' ]; then
        [ -z "$long_str" ] || echo ${long_str:1}
        long_str=""
        echo $i
    else
        long_str="$long_str $i"
    fi
done
[ -z "$long_str" ] || echo ${long_str:1}

答案 2 :(得分:0)

您应该考虑引用传递给脚本的参数:

例如:

图表A:

script.sh -a one string here -b another string here

图表B:

script.sh -a "one string here" -b "another string here"

和script.sh:

echo "$1:$2:$3:$4"

使用图表A,脚本将显示:-a:one:string:here

使用图B,脚本将显示:-a:这里有一个字符串:-b:这里是另一个字符串

我用冒号分隔东西,使其更明显。

在Bash中,如果你引用参数来禁止字符串的标记化,那么强制你的空格分隔字符串只是一个标记,而不是很多。

作为旁注,你应该引用你在Bash中使用的每个变量,只是因为它的值包含令牌分隔符(空格,制表符等),因为“$ var”和$ var是两个不同的事情,特别是如果var =“带空格的字符串”。

为什么呢?因为有一点你可能会想要这样的东西:

script.sh -a "a string with -b in it" -b "another string, with -a in it"

如果您不使用带引号的参数,而是尝试使用启发式算法来查找下一个参数的位置,那么当您的代码遇到伪造的-a和-b令牌时,您的代码将会生效。