$ *和$ @有什么区别?

Modified on: Sat, 30 Jun 2018 05:24:00 +0800

请考虑以下代码:

foo () {
    echo $*
}

bar () {
    echo $@
}

foo 1 2 3 4
bar 1 2 3 4

输出:

  

1 2 3 4

  
  

1 2 3 4

我正在使用Ksh88,但我也对其他常见的shell感兴趣。如果你碰巧知道特定贝壳的任何特殊性,请提及它们。

我在Solaris上的Ksh手册页中找到了以下内容:

  

$ *和$ @的含义是
  未引用时或作为参数使用时相同
  赋值或文件名。但是,当用作
  命令参数,$ *相当于``$ 1d $ 2d ...'',其中d
  是IFS变量的第一个字符,而$ @是
  相当于$ 1 $ 2 ....

我尝试修改IFS变量,但它不会修改输出。也许我做错了什么?

作者:Gilles,rahmu

最佳答案

如果没有引用它们,$*$@是相同的。您不应该使用其中任何一个,因为只要您的参数包含空格或通配符,它​​们就会意外中断。


"$*"扩展为单个字"$1c$2c..."。通常c是一个空格,但它实际上是IFS的第一个字符,所以它可以是你选择的任何东西。

我找到的唯一好处是:

用逗号加入参数(简单版)

join1() {
    IFS=,
    echo "$*"
}

join1 a b c   # => a,b,c

使用指定的分隔符连接参数(更好的版本)

join2() {
    typeset IFS=$1   # typeset makes a local variable in ksh (see footnote)
    shift
    echo "$*"
}

join2 + a b c   # => a+b+c


"$@"扩展为单独的单词:"$1" "$2" ... < / p>

这几乎总是你想要的。它将每个位置参数扩展为一个单独的单词,这使得它非常适合于获取命令行或函数参数,然后将它们传递给另一个命令或函数。并且因为它使用双引号扩展,这意味着如果"$1"包含空格或星号(*),事情就不会中断。


让我们编写一个名为svim的脚本,它使用vim运行sudo。我们将做三个版本来说明差异。

svim1

#!/bin/sh sudo vim $*

svim2

#!/bin/sh sudo vim "$*"

svim3

#!/bin/sh sudo vim "$@"

对于简单的情况,所有这些都可以,例如单个文件名,不包含空格:

#!/bin/sh
sudo vim $*

但如果您有多个参数,则只有$*"$@"才能正常工作。

#!/bin/sh
sudo vim "$*"

如果您的参数包含空格,则只有"$*""$@"才能正常工作。

#!/bin/sh
sudo vim "$@"

所以只有"$@"才能正常运作。


typeset是如何在kshbashash使用local而不是)。这意味着当函数返回时,IFS将恢复为其先前的值。这很重要,因为如果IFS设置为非标准的,那么之后运行的命令可能无法正常工作。

作者:,Mikel

相关问答

添加新评论