您必须了解 Unix 如何解释您的输入。
标准的 Unix shell在将参数传递给程序之前会插入环境变量以及所谓的glob 。这与使程序解释扩展的 Windows 有点不同。
尝试这个:
$ echo *
这将回显当前目录中的所有文件和目录。在echo
命令执行之前,shell 会插入*
并扩展它,然后将该扩展参数传递回您的命令。您可以通过执行以下操作来查看它的实际效果:
$ set -xv
$ echo *
$ set +xv
set -xv
打开xtrace和verbose。_ Verbose 回显输入的命令,而xtrace回显将要执行的命令(即在 shell 扩展之后)。
现在试试这个:
$ echo "*"
请注意,将某些内容放在引号中会对 shell 隐藏glob 表达式,并且 shell 无法扩展它。尝试这个:
$ foo="this is the value of foo"
$ echo $foo
$ echo "$foo"
$ echo '$foo'
请注意,shell 仍然可以在双引号内展开环境变量,但不能在单引号内展开。
现在让我们看看你的陈述:
file="home/edward/bank1/fiche/Test*"
双引号防止 shell 扩展glob 表达式,因此file
等于文字home/edward/bank1/finche/Test*
。因此,您需要这样做:
file=/home/edward/bank1/fiche/Test*
缺少引号(以及重要的介绍性斜线!)现在将使文件等于与该表达式匹配的所有文件。(可能不止一个!)。如果没有文件,取决于外壳程序及其设置,外壳程序可能只是将文件设置为该文字字符串。
你当然有正确的想法:
file=/home/edward/bank1/fiche/Test*
if test -s $file
then
echo "found one"
else
echo "found none"
fi
但是,如果有多个文件,您仍然可能会发现没有返回。相反,您可能会在命令中收到错误,test
因为参数太多。
解决此问题的一种方法可能是:
if ls /home/edward/bank1/finche/Test* > /dev/null 2>&1
then
echo "There is at least one match (maybe more)!"
else
echo "No files found"
fi
在这种情况下,我利用了ls
命令的退出代码。如果ls
找到一个它可以访问的文件,它会返回一个零退出代码。如果找不到匹配的文件,则返回非零退出代码。该if
命令仅执行一个命令,然后如果该命令返回零,则假定该if
语句为真并执行该if
子句。如果命令返回非零值,if
则假定语句为假,并执行else
子句(如果有的话)。
该test
命令以类似的方式工作。如果test
为真,则该test
命令返回零。否则,该test
命令返回一个非零值。这对if
命令很有用。实际上,该命令有一个别名。test
尝试这个:
$ ls -li /bin/test /bin/[
i
打印出inode。inode是文件的真实 ID 。具有相同 ID 的文件是同一个文件。您可以看到,/bin/test
并且/bin/[
是相同的命令。这使得以下两个命令相同:
if test -s $file
then
echo "The file exists"
fi
if [ -s $file ]
then
echo "The file exists"
fi