这将检查文件是否存在:
#!/bin/bash
FILE=$1
if [ -f $FILE ]; then
echo "File $FILE exists."
else
echo "File $FILE does not exist."
fi
如何仅检查文件是否不存在?
这将检查文件是否存在:
#!/bin/bash
FILE=$1
if [ -f $FILE ]; then
echo "File $FILE exists."
else
echo "File $FILE does not exist."
fi
如何仅检查文件是否不存在?
当前回答
envfile=.env
if [ ! -f "$envfile" ]
then
echo "$envfile does not exist"
exit 1
fi
其他回答
测试命令(此处写为[)有一个“not”逻辑运算符!(感叹号):
if [ ! -f /tmp/foo.txt ]; then
echo "File not found!"
fi
要反转测试,请使用“!”。这相当于其他语言中的“not”逻辑运算符。试试看:
if [ ! -f /tmp/foo.txt ];
then
echo "File not found!"
fi
或以稍微不同的方式书写:
if [ ! -f /tmp/foo.txt ]
then echo "File not found!"
fi
或者您可以使用:
if ! [ -f /tmp/foo.txt ]
then echo "File not found!"
fi
或者,将所有内容放在一起:
if ! [ -f /tmp/foo.txt ]; then echo "File not found!"; fi
可以写成(使用“and”运算符:&&):
[ ! -f /tmp/foo.txt ] && echo "File not found!"
看起来像这样更短:
[ -f /tmp/foo.txt ] || echo "File not found!"
In
[ -f "$file" ]
[命令对$file中存储的路径执行stat()(而不是lstat())系统调用,如果系统调用成功并且stat()返回的文件类型为“正则”,则返回true。
因此,如果[-f“$file”]返回true,则可以判断该文件确实存在,并且是一个常规文件或符号链接,最终解析为常规文件(或者至少在stat()时是这样)。
但是,如果它返回false(或者如果[!-f“$file”]或![-f“$file“]返回true),则有很多不同的可能性:
文件不存在该文件存在,但不是常规文件(可以是设备、fifo、目录、套接字…)文件存在,但您没有对父目录的搜索权限文件存在,但访问该文件的路径太长该文件是到常规文件的符号链接,但您没有对符号链接解析中涉及的某些目录的搜索权限。…stat()系统调用可能失败的任何其他原因。
简而言之,它应该是:
if [ -f "$file" ]; then
printf '"%s" is a path to a regular file or symlink to regular file\n' "$file"
elif [ -e "$file" ]; then
printf '"%s" exists but is not a regular file\n' "$file"
elif [ -L "$file" ]; then
printf '"%s" exists, is a symlink but I cannot tell if it eventually resolves to an actual file, regular or not\n' "$file"
else
printf 'I cannot tell if "%s" exists, let alone whether it is a regular file or not\n' "$file"
fi
为了确定文件不存在,我们需要stat()系统调用返回错误代码ENOENT(ENOTDIR告诉其中一个路径组件不是目录,这是另一种情况,我们可以通过该路径判断文件不存在)。不幸的是,[命令没有让我们知道这一点。无论错误代码是ENOENT、EACESS(权限被拒绝)、ENAMETOOLONG或其他什么,它都会返回false。
[-e“$file”]测试也可以使用ls-Ld--“$file“>/dev/null完成。在这种情况下,ls将告诉您stat()失败的原因,尽管这些信息不能很容易地以编程方式使用:
$ file=/var/spool/cron/crontabs/root
$ if [ ! -e "$file" ]; then echo does not exist; fi
does not exist
$ if ! ls -Ld -- "$file" > /dev/null; then echo stat failed; fi
ls: cannot access '/var/spool/cron/crontabs/root': Permission denied
stat failed
至少ls告诉我它失败并不是因为文件不存在。这是因为它无法判断文件是否存在。[命令只是忽略了这个问题。
使用zsh shell,您可以在[命令失败后使用$ERRNO特殊变量查询错误代码,并使用zsh/system模块中的$errnos特殊数组解码该数字:
zmodload zsh/system
ERRNO=0
if [ ! -f "$file" ]; then
err=$ERRNO
case $errnos[err] in
("") echo exists, not a regular file;;
(ENOENT|ENOTDIR)
if [ -L "$file" ]; then
echo broken link
else
echo does not exist
fi;;
(*) syserror -p "can't tell: " "$err"
esac
fi
(注意,当使用最新版本的gcc构建zsh时,$errnos支持被一些版本破坏)。
我更喜欢使用POSIX shell兼容格式执行以下一行代码:
$ [ -f "/$DIR/$FILE" ] || echo "$FILE NOT FOUND"
$ [ -f "/$DIR/$FILE" ] && echo "$FILE FOUND"
对于一些命令,就像我在脚本中所做的那样:
$ [ -f "/$DIR/$FILE" ] || { echo "$FILE NOT FOUND" ; exit 1 ;}
一旦我开始这样做,我就很少再使用完全类型化的语法了!!
此shell脚本还可用于查找目录中的文件:
echo "enter file"
read -r a
if [ -s /home/trainee02/"$a" ]
then
echo "yes. file is there."
else
echo "sorry. file is not there."
fi