2010-06-24 22 views
0

如何创建这个小脚本?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 

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

感谢

+0

目前尚不清楚你想要什么。你是否想要将标志-a,-b和-c分开,并且在列表中分别拥有一组其他参数?另外,你是否正在寻找一种不使用引号或多个单词参数的方法? – Slartibartfast 2010-06-24 02:12:39

+0

我想要的是,每当有一个参数(-a或-b或其他)时,脚本在此之后捕获所有字符串,并将其放入一个变量中,我还需要检查带有大小写或其他模式的参数。我知道如何使这只有一个参数,但具有多个参数?谢谢。 – fixo2020 2010-06-24 03:05:43

回答

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规范和约定来连接这样的参数。

+0

谢谢先生,但你的建议是更好的引用或没有它? – fixo2020 2010-06-24 12:55:02

+0

你可以更具体地了解你的程序做什么,这些选项是什么? – 2010-06-24 13:00:17

+0

是更新任何社交网络的客户端,我想让它并发,例如,-b更新facebook -t更新twitter -x更新其他社交网络。 – fixo2020 2010-06-24 13:49:02

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} 
0

你应该看看引用传递给脚本的参数:

例如:

附件A:

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

附件B:

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

和脚本.sh:

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

用Exhibit A,该脚本将显示:-a:一个:字符串:这里

用Exhibit B,该脚本将显示:-a:一个字符串这里:-b:另一个串这里

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

在Bash中,如果引用了禁止字符串标记的参数,则强制空格分隔的字符串只是一个标记,而不是许多标记。因为“$ var”和$ var是两个,所以你应该引用你在Bash中使用的每个变量,仅用于其值包含标记分隔符(空格,制表符等)的情况。不同的东西,特别是如果var =“带空格的字符串”。

为什么?因为在一个点上,你可能会想是这样的:

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

如果你不使用引用参数,而是学尝试试探法来找到下一个参数是,你的代码将当它击中制动假-a和-b令牌。