«

如何在Bash中检查一个文件或目录是否存在

时间:2024-2-22 14:06     作者:韩俊     分类: Linux


很多时候,在编写Shell脚本时,你可能会发现自己处于这样一种情况:你需要根据一个文件的存在与否来执行一个动作。

在Bash中,你可以使用test命令来检查一个文件是否存在,并确定该文件的类型。

测试命令采用以下语法形式之一:

test EXPRESSION
[ EXPRESSION ]
[[ EXPRESSION ]]

如果你希望你的脚本是可移植的,你应该倾向于使用旧的测试[命令,它在所有的POSIX shell上都可用。新的升级版测试命令[[(双括号)在大多数使用Bash、Zsh和Ksh作为默认shell的现代系统中都支持。

检查文件是否存在

当检查一个文件是否存在时,最常用的 FILE 操作符是 -e 和 -f 。第一个运算符将检查一个文件是否存在,而第二个运算符只在 FILE 是一个普通的文件(不是一个目录或设备)时返回真。

在检查一个文件是否存在时,最可读的选择是使用 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 命令。只有当测试命令的 exit status 为真时,&& 操作符后的命令才会被执行。

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/; }

与 && 相反,只有当测试命令的退出状态为 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

或者

[ -f /etc/resolv.conf -a -f /etc/hosts ] && echo "Both files exist."

或者

[[ -f /etc/resolv.conf && -f /etc/hosts ]] && echo "Both files exist."

文件测试操作符

测试命令包括以下FILE操作符,允许你测试特定类型的文件。

-b FILE - 如果FILE存在,并且是一个特殊的块状文件,则为真。
-c FILE - 如果FILE存在,并且是一个特殊字符的文件,则为真。
-d FILE - 如果FILE存在并且是一个目录,则为 "真"。
-e FILE - 如果FILE存在并且是一个文件,则为真,无论其类型如何(节点、目录、套接字等)。
-f FILE - 如果FILE存在并且是一个普通的文件(而不是一个目录或设备),则为真。
-G FILE - 如果FILE存在,并且与运行命令的用户有相同的组,则为真。
-h FILE - 如果FILE存在,并且是一个符号链接,则为真。
-g FILE - 如果FILE存在并且设置了set-group-id(sgid)标志,则为真。
-k FILE - 如果FILE存在并且有一个粘性位标志被设置,则为真。
-L FILE - 如果FILE存在,并且是一个符号链接,则为真。
-O FILE - 如果FILE存在并且为运行命令的用户所拥有,则为 "true"。
-p FILE - 如果FILE存在,并且是一个管道,则为真。
-r FILE - 如果FILE存在并且可以被读取,则为真。
-S FILE - 如果FILE存在并且是一个套接字,则为 "真"。
-s FILE - 如果FILE存在并且大小不为零,则为真。
-u FILE - 如果FILE存在,并且设置了set-user-id(suid)标志,则为真。
-w FILE - 如果FILE存在并且是可写的,则为真。
-x FILE - 如果FILE存在并且是可执行的,则为真。

标签: linux

热门推荐