很多时候编写Shell脚本时,您可能会发现自己处于需要根据文件是否存在执行操作的情况。
在Bash中,可以使用test命令检查文件是否存在并确定文件的类型。
test命令采用以下语法格式之一:
test EXPRESSION
[ EXPRESSION ]
[[ EXPRESSION ]]如果希望脚本具有可移植性,则应首选使用旧的test[命令,该命令在所有POSIX shell上都可用。[[使用Bash,Zsh和Ksh作为默认Shell的大多数现代系统都支持test命令的新升级版本(双括号)。文章目录
-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。