【问题标题】:Using $@ properly正确使用 $@
【发布时间】:2009-10-16 13:33:15
【问题描述】:

我正在尝试编写一个小脚本,它接受任意数量的命令行参数,打印出文件(不是目录)的rwx 权限

我拥有的是

file=$@    
if [ -f $file ] ; then    
ls -l $file    
fi

然而,它只接受一个命令行参数。感谢您的帮助。

【问题讨论】:

  • 我很感兴趣,这似乎与您的其他一些问题密切相关 - 愿意提供更多背景信息吗?

标签: bash unix variables


【解决方案1】:

这里演示了$*$@ 之间的一些区别,带引号和不带引号:

#/bin/bash
for i in $*; do
    echo "\$*: ..${i}.."
done; echo
for i in "$*"; do
    echo "\"\$*\": ..${i}.."
done; echo
for i in $@; do
    echo "\$@: ..${i}.."
done; echo
for i in "$@"; do
    echo "\"\$@\": ..${i}.."
done; echo

运行它:

user@host$ ./paramtest abc "space here"
$*: ..abc..
$*: ..space..
$*: ..here..

"$*": ..abc space here..

$@: ..abc..
$@: ..space..
$@: ..here..

"$@": ..abc..
"$@": ..space here..

【讨论】:

    【解决方案2】:

    这个怎么样:

    for file
    do
        test -f "$file" && ls -l "$file"
    done
    

    默认情况下 for 循环将在 $@ 上运行,因此您不必提及它。请注意,如果文件名包含空格,则需要引用“$file”。例如,如果您将脚本保存到“myll.sh”:

    $ myll.sh "My Report.txt" file1 file2
    

    然后“My Report.txt”将作为一个整体令牌而不是两个单独的令牌传入:“My”和“Report.txt”

    【讨论】:

    • 为了清楚起见,我认为通常最好包含$@
    • 这是一个品味问题,但我同意你的看法。我已经包含 $@ 很长时间了,但最近才停止这样做。
    【解决方案3】:

    您想要的变量确实是$@ - 它包含所有作为单独单词的命令行参数,每个都原封不动地传递(没有扩展)。 ($* 将它们全部视为一个单词 - 如果文件名中有空格,祝你好运。

    如果你愿意,你可以循环播放。这很容易扩展到比ls 更复杂的操作。

    for file in "$@"; do
        if [ -f "$file" ]; then
            ls -l "$file"
        fi
    done
    

    注意:您应该引用$@ 以保护其中的任何特殊字符!出于同样的原因,您还应该引用$file - 特别是在测试中。如果$@ 中有一个空字符串,file 也将为空,并且没有引号,-f 将尝试作用于']'。错误随之而来。

    另外,如果您只需要ls(跳过您的if),您可以这样做:

    ls -l "$@"
    

    【讨论】:

      【解决方案4】:

      您可以有效地遍历任何这样指定的文件:

      for file in "$@"; do
        ls -l "$file"
      done
      

      如果您想仔细检查指定的名称是否不是目录,您可以这样做:

      for file in "$@"; do
        if [ ! -d "$file" ]; then
          ls -l "$file"
        fi
      done
      

      【讨论】:

      • $@$file 应该被引用以保护空格和其他特殊字符。
      • 完全正确-我的想法太懒惰了。非常感谢。现在已修复。 :-)
      【解决方案5】:

      传递给脚本的所有参数的 bash 变量是“$*”。试试:

      for file in $*; do
        if [ -f $file ] ; then
          ls -l $file
        fi
      done
      

      (未测试)

      【讨论】:

      • 这不适用于包含空格的参数。始终使用 "$@" 代替,并引用所有变量。
      猜你喜欢
      • 2018-11-03
      • 1970-01-01
      • 2014-08-05
      • 2012-11-08
      • 2015-06-09
      • 2021-02-02
      • 2013-07-14
      • 2018-06-30
      • 2017-12-01
      相关资源
      最近更新 更多