【发布时间】:2009-10-16 13:33:15
【问题描述】:
我正在尝试编写一个小脚本,它接受任意数量的命令行参数,打印出文件(不是目录)的rwx 权限
我拥有的是
file=$@
if [ -f $file ] ; then
ls -l $file
fi
然而,它只接受一个命令行参数。感谢您的帮助。
【问题讨论】:
-
我很感兴趣,这似乎与您的其他一些问题密切相关 - 愿意提供更多背景信息吗?
我正在尝试编写一个小脚本,它接受任意数量的命令行参数,打印出文件(不是目录)的rwx 权限
我拥有的是
file=$@
if [ -f $file ] ; then
ls -l $file
fi
然而,它只接受一个命令行参数。感谢您的帮助。
【问题讨论】:
这里演示了$* 和$@ 之间的一些区别,带引号和不带引号:
#/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..
【讨论】:
这个怎么样:
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”
【讨论】:
$@。
您想要的变量确实是$@ - 它包含所有作为单独单词的命令行参数,每个都原封不动地传递(没有扩展)。 ($* 将它们全部视为一个单词 - 如果文件名中有空格,祝你好运。
如果你愿意,你可以循环播放。这很容易扩展到比ls 更复杂的操作。
for file in "$@"; do
if [ -f "$file" ]; then
ls -l "$file"
fi
done
注意:您应该引用$@ 以保护其中的任何特殊字符!出于同样的原因,您还应该引用$file - 特别是在测试中。如果$@ 中有一个空字符串,file 也将为空,并且没有引号,-f 将尝试作用于']'。错误随之而来。
另外,如果您只需要ls(跳过您的if),您可以这样做:
ls -l "$@"
【讨论】:
您可以有效地遍历任何这样指定的文件:
for file in "$@"; do
ls -l "$file"
done
如果您想仔细检查指定的名称是否不是目录,您可以这样做:
for file in "$@"; do
if [ ! -d "$file" ]; then
ls -l "$file"
fi
done
【讨论】:
$@ 和 $file 应该被引用以保护空格和其他特殊字符。
传递给脚本的所有参数的 bash 变量是“$*”。试试:
for file in $*; do
if [ -f $file ] ; then
ls -l $file
fi
done
(未测试)
【讨论】: