Bash中检测文件或目录是否存在
嘻嘻发布于2020-12-17
最后更新于2020年12月16日
浏览很多时候编写Shell脚本时,您可能会发现自己处于需要根据文件是否存在执行操作的情况。
在Bash中,可以使用test命令检查文件是否存在并确定文件的类型。
test命令采用以下语法格式之一:
test EXPRESSION
[ EXPRESSION ]
[[ EXPRESSION ]]
如果希望脚本具有可移植性,则应首选使用旧的test[
命令,该命令在所有POSIX shell上都可用。[[
使用Bash,Zsh和Ksh作为默认Shell的大多数现代系统都支持test命令的新升级版本(双括号)。
检查文件是否存在
检查文件是否存在时,最常用的FILE运算符是-e
和-f
。第一个将检查文件是否存在而与类型无关,而第二个将仅在FILE是常规文件(而不是目录或设备)时返回true。
检查文件是否存在时,最易读的选项是将test
命令与if
语句结合使用。以下任何代码段都将检查/etc/resolv.conf
文件是否存在:
FILE=/etc/resolv.conf
if test -f "$FILE"; then
echo "$FILE exists."
fi
FILE=/etc/resolv.conf
if [ -f "$FILE" ]; then
echo "$FILE exists."
fi
FILE=/etc/resolv.conf
if [[ -f "$FILE" ]]; then
echo "$FILE exists."
fi
如果要基于文件是否存在执行其他操作,只需使用if / then构造:
FILE=/etc/resolv.conf
if [ -f "$FILE" ]; then
echo "$FILE exists."
else
echo "$FILE does not exist."
fi
您也可以使用不带if语句的test命令。&&
仅当测试命令的退出状态为true时,才执行操作员之后的命令,
test -f /etc/resolv.conf && echo "$FILE exists."
[ -f /etc/resolv.conf ] && echo "$FILE exists."
[[ -f /etc/resolv.conf ]] && echo "$FILE exists."
如果要在&&
运算符后运行一系列命令,只需将命令括在用;
或括起来的大括号中&&
:
[ -f /etc/resolv.conf ] && { echo "$FILE exist."; cp "$FILE" /tmp/; }
相反&&
,||
仅当test命令的退出状态为时,才执行运算符后的语句false
。
[ -f /etc/resolv.conf ] && echo "$FILE exist." || echo "$FILE does not exist."
检查目录是否存在
操作员-d
可让您测试文件是否为目录。
例如,要检查/etc/docker
目录是否存在,可以使用:
FILE=/etc/docker
if [ -d "$FILE" ]; then
echo "$FILE is a directory."
fi
[ -d /etc/docker ] && echo "$FILE is a directory."
您也可以使用双括号[[
而不是单个括号[
。
检查文件是否不存在
与许多其他语言相似,可以使用!
(感叹号)逻辑非运算符来否定测试表达式:
FILE=/etc/docker
if [ ! -f "$FILE" ]; then
echo "$FILE does not exist."
fi
与上述相同:
[ ! -f /etc/docker ] && echo "$FILE does not exist."
检查是否存在多个文件
您可以使用-a
(或&&
与[[
)来测试是否存在多个文件,而不是使用复杂的嵌套if / else构造:
if [ -f /etc/resolv.conf -a -f /etc/hosts ]; then
echo "Both files exist."
fi
if [[ -f /etc/resolv.conf && -f /etc/hosts ]]; then
echo "Both files exist."
fi
不使用IF语句的等效变体:
[ -f /etc/resolv.conf -a -f /etc/hosts ] && echo "Both files exist."
[[ -f /etc/resolv.conf && -f /etc/hosts ]] && echo "Both files exist."
文件测试操作员
test命令包括以下FILE运算符,可让您测试特定类型的文件:
-b
FILE
-如果FILE存在并且是特殊的块文件,则为true。-c
FILE
-如果FILE存在并且是特殊字符文件,则为true。-d
FILE
-如果FILE存在并且是目录,则为true。-e
FILE
-如果FILE存在且是文件,则与True无关,而与类型(节点,目录,套接字等)无关。-f
FILE
-如果FILE存在并且是常规文件(不是目录或设备),则为true。-G
FILE
-如果FILE存在并且与运行命令的用户具有相同的组,则为true。-h
FILE
-如果FILE存在并且是符号链接,则为true。-g
FILE
-如果FILE存在并且设置了set-group-id(sgid
)标志,则为true 。-k
FILE
-如果FILE存在并且设置了粘性位标志,则为true。-L
FILE
-如果FILE存在并且是符号链接,则为true。-O
FILE
-如果FILE存在并且由运行命令的用户拥有,则为True。-p
FILE
-如果FILE存在并且是管道,则为true。-r
FILE
-如果FILE存在且可读,则为true。-S
FILE
-如果FILE存在并且是套接字,则为true。-s
FILE
-如果FILE存在且大小非零,则为true。-u
FILE
-如果FILE存在并且设置了set-user-id(suid
)标志,则为true 。-w
FILE
-如果FILE存在且可写,则为true。-x
FILE
-如果FILE存在且可执行,则为true。