这是我的代码:
if [ "$#" -eq 0 ]; then
echo "no params"
elif [ "$#" -eq 1 ]; then
if [ "$1" = "*" ] ; then
# do something
else echo "bad params"
fi
else echo "more than 1 param"
fi
问题是当我用
启动脚本时 sh script.sh *
它将打印超过1个参数cause the " * " will search for all files
,
我的问题是如何禁用搜索文件。
答案 0 :(得分:2)
脚本无法判断它是否作为参数或文件列表传递了不带引号的*
,因为在shell实际调用脚本之前,它会将*
替换为列表该通配符匹配的文件。
因此,如果不要求用户引用,您所要求的行为是不可能的:
your-script '*'
答案 1 :(得分:2)
引用星号以防止外壳扩展
sh script.sh "*"
或首先禁用文件名生成:
set -f
sh script.sh *
set +f # Re-enable afterwards
第二种方法并不是真的值得推荐的;关闭文件名扩展可能会在以后产生意想不到的后果,与简单引用星号相比,它打字很多。
答案 2 :(得分:0)
您必须引用星号*
,否则它会扩展到当前目录中的文件(请参阅globbing)。
$ sh script.sh "*"
答案 3 :(得分:0)
试试这个:
$ echo * # Note: No quotation marks
您将获得文件和目录的列表。
现在试试这个:
$ echo "*" # Note the quotes around the asterisk
在这里,你只会得到一个星号。
在程序执行之前,shell会抓取参数并展开它们。
这是因为Unix中的shell非常智能。它很好,因为这意味着我的程序不必解释*.txt
的含义。 shell处理它。这也意味着如果我想将*
传递给shell脚本,我需要引用它。
报价通常可以通过三种方式完成:
$echo "*"
$echo \*
使用双引号几乎是标准。它并没有完全阻止shell破坏你的命令行。 shell将插入shell变量,但它将停止所谓的 globbing ,其中shell将尝试将专用字符扩展为文件名。
$ foo="bar"
$ echo "$foo *"
$ echo bar *
使用单引号将使shell完全不受影响。它甚至不会尝试插入变量。
$ foo="bar"
$ echo '$foo *'
$foo *
使用反斜杠可防止shell对下一个字符执行任何操作。它就像单引号,但你不必担心结束语:
$ echo \$foo \*
$ $foo *
因此,您的shell脚本没有任何问题。您的shell脚本正在检测是否正在向其传递星号。问题是shell正在拦截您传递给命令的参数,看到星号,并在程序开始执行之前将其替换为目录中所有文件的列表。
您可以通过输入以下命令来查看:
$ set -xv
现在,尝试使用星号运行您的程序。
$ myprog *
set -xv
命令将显示shell在程序执行之前传递给程序的内容。 set -xv
,但他们的方式,在调试shell脚本时非常有用,所以很高兴知道。
要关闭set -xv
,请输入:
$ set +xv