红联Linux门户
Linux帮助

[已解决]Shell 参数传递问题

发布时间:2011-04-21 21:05:36来源:红联作者:wewe-b
[i=s] 本帖最后由 wewe-b 于 2011-4-27 10:25 编辑 [/i]

如果一个参数中有空格,用引号包括参数表示,但传入脚本中会被分成两个参数。例如一个 test 脚本:[code]#!/bin/bash
rm $*[/code]#删除当前路径的 First dir 目录
./test -r "First dir"

./test -r '"First dir"'

这样都会被分隔成 First 和 dir 两个参数。
请问该如何解决?
文章评论

共有 3 条评论

  1. wewe-b 于 2011-04-26 13:41:03发表:

    终于有高手回贴了。
    非常感谢谢楼上两位指教。

    谢谢“age” 的详细举例说明。您提供的链接正是我需要的资料。

  2. age 于 2011-04-26 08:45:44发表:

    [i=s] 本帖最后由 age 于 2011-4-26 10:58 编辑 [/i]

    三种方法,
    1. 把$*改为$@. 对于多个词时, "$*"会把后面所有的参数赋值给一个变量, 即"$1 $2 $3..".而"$@"则把每个参数赋与一个变量, 即"$1", "$2", "$3"....

    2. 改用循环做, 注意为了简化, 我用echo代替了rm, 以免来回创建目录, 效果是一样的.[code]#!/bin/bash
    while [ $# -ne 0 ]
    do
    echo "$1"
    shift
    done[/code]这里的关键是$n的确定, 因为"$"本身就是bash的变量引用符号, 所以不能简单的用$i, $($(i))这样的变量方式来表示$2, $3等. 此时只能用shift参数, 它的作用删除前一位, 并把后面参数前移, 同时会将$#值减一(因为前个参数已被抛弃了).
    以此来实现对$n的循环检测, 执行.
    另外就是$1与"$1"的区别, 对于echo来说, echo first dir与echo "first dir"效果是相同的, 因为空格不会影响输出. 但对于rm来说这就有很大的区别的, rm -r first dir, 相当于对first和dir二个目录进行操作, 这显然是不对的, rm -r "first dir" 才是正确的写法. 此处多谢yanyongkg提醒(so):)

    3. 还是循环, 但不用shift, 而是借助$@,和方法1原理差不多. 此时把#@作为一个列表, 直接从这个列表中抽到数据, 而不再考虑$1, $2这些变量.[code]#!/bin/bash
    for i in "$@"
    do
    echo "$i"
    done[/code]几个要点, $*, "$*"都不行, 因为$*会把空格符作为参数结束标志, 从而把目录名称给切割了, 而后面是把所以参数赋与一个变量.
    此处可以展示这4种表达方式的区别.
    当为$*时[code][allblue@MyLady test]$ ./test.sh "first dir" "second dir"
    first
    dir
    second
    dir[/code]当为"$*"时[code][allblue@MyLady test]$ ./test.sh "first dir" "second dir"
    first dir second dir[/code]同理不加双引号的$@与$*效果相同[code][allblue@MyLady test]$ ./test.sh "first dir" "second dir"
    first
    dir
    second
    dir[/code]最后正确的写法, "$@"[code][allblue@MyLady test]$ ./test.sh "first dir" "second dir"
    first dir
    second dir[/code]更具体的可参看该网页. http://www.ibm.com/developerworks/cn/linux/l-bash-parameters.html

  3. yanyongkg 于 2011-04-26 00:23:49发表:

    [i=s] 本帖最后由 yanyongkg 于 2011-4-26 00:46 编辑 [/i]

    脚本如下:
    #!/bin/bash
    rm -r "$*"

    执行:
    ./test "First dir"

    上面的方法还有问题,此方法只能用于删除一个文件的情况!

    下面这样是不行的:
    #!/bin/bash
    rm "$*"

    执行:
    ./test -r "First dir"
    这样会把 -r也读进$*去了成了执行rm '-r First dir',而不是执行rm -r 'First dir'