如何判断Bash中是否不存在常规文件?
我使用以下脚本查看文件是否存在:如何判断Bash中是否不存在常规文件?,bash,file-io,scripting,Bash,File Io,Scripting,我使用以下脚本查看文件是否存在: #!/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 [ $FILE does not exist ]; then echo "File $FILE does
#!/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 [ $FILE does not exist ]; then
echo "File $FILE does not exist."
fi
命令([
此处)有一个“not”逻辑运算符,它是感叹号(类似于许多其他语言)。请尝试以下操作:
if [ ! -f /tmp/foo.txt ]; then
echo "File not found!"
fi
if [ ! -f /tmp/foo.txt ];
then
echo "File not found!"
fi
可以用“!”来否定表达式: 对于内置bash命令,相关的手册页是
man test
,或者相当于man[
——或者help test
或者help[
[[ -f $FILE ]] || printf '%s does not exist!\n' "$FILE"
此外,该文件可能是断开的符号链接,或者是非常规文件,例如套接字、设备或fifo。例如,要添加对断开符号链接的检查:
if [[ ! -f $FILE ]]; then
if [[ -L $FILE ]]; then
printf '%s is a broken symlink!\n' "$FILE"
else
printf '%s does not exist!\n' "$FILE"
fi
fi
-r: Returns true if file exists and is readable
-w: Returns true if file exists and is writable
-x: Returns true if file exists and is executable
-s: Returns true if file exists and has a size > 0
值得一提的是,如果需要执行单个命令,可以缩写为
if [ ! -f "$file" ]; then
echo "$file"
fi
到
或
我更喜欢以与shell兼容的格式执行以下一行程序:
$ [ -f "/$DIR/$FILE" ] || echo "$FILE NOT FOUND"
$ [ -f "/$DIR/$FILE" ] && echo "$FILE FOUND"
对于几个命令,就像我在脚本中所做的那样:
$ [ -f "/$DIR/$FILE" ] || { echo "$FILE NOT FOUND" ; exit 1 ;}
一旦我开始这样做,我就很少再使用完全类型化语法了!!对于一个不带引号的变量,在运行
test
时应该小心,因为它可能会产生意外的结果:
$ [ -f ]
$ echo $?
0
$ [ -f "" ]
$ echo $?
1
通常建议将被测变量用双引号括起来:
#!/bin/sh
FILE=$1
if [ ! -f "$FILE" ]
then
echo "File $FILE does not exist."
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
或者,一起预测:
if ! [ -f /tmp/foo.txt ]; then echo "File not found!"; fi
可将其写入(使用then“and”运算符:&&&)为:
它看起来像这样短:
[ -f /tmp/foo.txt ] || echo "File not found!"
此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
要测试文件是否存在,参数可以是以下任意一个:
-e: Returns true if file exists (regular file, directory, or symlink)
-f: Returns true if file exists and is a regular file
-d: Returns true if file exists and is a directory
-h: Returns true if file exists and is a symlink
以下所有测试均适用于常规文件、目录和符号链接:
if [[ ! -f $FILE ]]; then
if [[ -L $FILE ]]; then
printf '%s is a broken symlink!\n' "$FILE"
else
printf '%s does not exist!\n' "$FILE"
fi
fi
-r: Returns true if file exists and is readable
-w: Returns true if file exists and is writable
-x: Returns true if file exists and is executable
-s: Returns true if file exists and has a size > 0
示例脚本:
#!/bin/bash
FILE=$1
if [ -f "$FILE" ]; then
echo "File $FILE exists"
else
echo "File $FILE does not exist"
fi
Bash文件测试
-b文件名
-阻止特殊文件-c文件名
-特殊字符文件-d directoryname
-检查目录是否存在-e filename
-检查文件是否存在,而不考虑类型(节点、目录、套接字等)-f filename
-检查常规文件是否存在而不是目录-G filename
-检查文件是否存在并且是否由有效的组ID拥有-G filename set group id
-如果文件存在并且设置了组id,则为True-k文件名
-Sticky位-L文件名
-符号链接-O filename
-如果文件存在且由有效用户id拥有,则为True-r文件名
-检查文件是否可读-S文件名
-检查文件是否为套接字-s文件名
-检查文件大小是否为非零-u filename
-检查是否设置了文件集用户id位-w文件名
-检查文件是否可写-x文件名
-检查文件是否可执行
如何使用:
#!/bin/bash
file=./file
if [ -e "$file" ]; then
echo "File exists"
else
echo "File does not exist"
fi
可以使用!
运算符对测试表达式求反
#!/bin/bash
file=./file
if [ ! -e "$file" ]; then
echo "File does not exist"
else
echo "File exists"
fi
最简单的方法
FILE=$1
[ ! -e "${FILE}" ] && echo "does not exist" || echo "exists"
您可以这样做:
[[ ! -f "$FILE" ]] && echo "File doesn't exist"
或
如果要同时检查文件和文件夹,请使用
-e
选项,而不是-f
-e
为常规文件、目录、套接字、字符特殊文件、块特殊文件等返回true。此代码也有效
#!/bin/bash
FILE=$1
if [ -f $FILE ]; then
echo "File '$FILE' Exists"
else
echo "The File '$FILE' Does Not Exist"
fi
有三种不同的方法可以做到这一点:
[
中否定测试(这是以前大多数答案的表达方式):
或:
|
而不是&&
):
仅:
这看起来很愚蠢(IMO),除非您的代码必须可移植到缺少管道否定运算符(!
)的Bourne shell(如Solaris 10或更早版本的/bin/sh
),否则不要使用它:
[
命令对存储在$file
中的路径执行stat()
(而不是lstat()
)系统调用,如果系统调用成功且stat()
返回的文件类型为“常规”,则返回true
因此,如果[-f“$file”]
返回true,则可以判断该文件确实存在,并且是一个常规文件或符号链接,最终解析为常规文件(或者至少在stat()时是这样)
但是,如果返回false(或如果[!-f“$file”]
或![-f“$file”]
返回true),则有许多不同的可能性:
- 该文件不存在
- 该文件存在,但不是常规文件(可能是设备、fifo、目录、套接字…)
- 文件存在,但您没有父目录的搜索权限
- 文件存在,但访问该文件的路径太长
- 该文件是常规文件的符号链接,但您没有对符号链接解析中涉及的某些目录的搜索权限
- …系统调用可能失败的任何其他原因
简言之,应该是:
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()
系统调用返回一个错误代码enoint
(ENOTDIR
告诉我们其中一个路径组件不是目录,在另一种情况下,我们可以通过该路径判断文件不存在)。不幸的是[
命令不让我们知道这一点。无论错误代码是enoint、EACCESS(权限被拒绝)、enametolong还是其他任何代码,它都将返回false
[-e“$file”]
测试也可以使用ls-Ld--“$file”>/dev/null
完成。在这种情况下,ls
将告诉您原因
#!/bin/bash
FILE=$1
if [ -f $FILE ]; then
echo "File '$FILE' Exists"
else
echo "The File '$FILE' Does Not Exist"
fi
if ! [ -e "$file" ]; then
echo "file does not exist"
fi
! [ -e "$file" ] && echo "file does not exist"
if [ ! -e "$file" ]; then
echo "file does not exist"
fi
[ ! -e "$file" ] && echo "file does not exist"
[ -e "$file" ] || echo "file does not exist"
if [ -e "$file" ]; then
:
else
echo "file does not exist"
fi
[ -f "$file" ]
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
$ 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
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
test -b $FILE && echo File not there!
test -b $FILE || echo File there!
test1
test2
test3
if ! test "$FILE"; then
echo "does not exist"
fi
envfile=.env
if [ ! -f "$envfile" ]
then
echo "$envfile does not exist"
exit 1
fi