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

bash:在所有参数之后存储所有命令行参数,bash,Bash,如何创建这个小脚本 例如: ~$ script.sh -b my small string... other things -a other string -c any other string ant etc long_str="" for i; do if [ ${i:0:1} = '-' ]; then [ -z "$long_str" ] || echo ${long_str:1} long_str="" echo $i

如何创建这个小脚本

例如:

~$ script.sh -b my small string... other things -a other string -c any other string ant etc
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}
我只想要字符串,每个都有一个模式

-b
my small string... other things
-a
other string
-c
any other string ant etc
有人知道它是怎么实现的吗


谢谢

我考虑过用
getopt
来做这件事,但我认为它没有能力;将不带引号的分隔字符串视为一个参数是非常罕见的。我认为你将不得不手工操作;例如:

~$ script.sh -b my small string... other things -a other string -c any other string ant etc
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}

我研究过如何使用
getopt
,但我认为它没有能力;将不带引号的分隔字符串视为一个参数是非常罕见的。我认为你将不得不手工操作;例如:

~$ script.sh -b my small string... other things -a other string -c any other string ant etc
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}

这里有一个非常简单的命令行参数循环。命令行参数是
$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
$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规范和约定。

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

例如:

~$ script.sh -b my small string... other things -a other string -c any other string ant etc
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}
附件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:此处

对于附件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标记时,它将停止运行。

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

例如:

~$ script.sh -b my small string... other things -a other string -c any other string ant etc
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}
附件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:此处

对于附件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标记时,它将停止运行。

您不清楚需要什么。是否要将标志-a、-b和-c分开,并在列表中单独/包含一组其他参数?或者,您是否正在寻找一种不使用引号的多词参数的方法,或者…?我希望,无论何时,只要是一个参数,(-a或-b或其他),脚本都会捕获该参数之后的所有字符串,并将其放入变量中,我还需要使用大小写或其他模式检查参数。我知道如何只使用一个参数,而使用多个参数?谢谢。不清楚你想要什么。是否要将标志-a、-b和-c分开,并在列表中单独/包含一组其他参数?或者,您是否正在寻找一种不使用引号的多词参数的方法,或者…?我希望,无论何时,只要是一个参数,(-a或-b或其他),脚本都会捕获该参数之后的所有字符串,并将其放入变量中,我还需要使用大小写或其他模式检查参数。我知道如何只使用一个参数,而使用多个参数?谢谢。谢谢先生,但是你的建议最好是引用还是不引用?你能更具体地说明你的程序做什么,这些选项是什么吗?是一个用于更新任何社交网络的客户端,我想同时进行,例如,-b更新facebook-t更新twitter-x更新其他社交网络。好的,是的,那么,一定要求用户使用引号。先生,我有一个最后的问题,当使用它时:-一个'string'string2'为什么?谢谢先生,但是你的建议最好使用引号或不使用引号?你能更具体地说明你的程序做什么,这些选项是什么吗?是更新任何社交网络的客户端吗,我想要