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

时间:2020-03-05 15:31:35  来源:igfitidea点击:

很多时候编写Shell脚本时,我们可能会发现自己需要根据文件是否存在执行操作。

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

test命令采用以下语法格式之一:

test EXPRESSION
[ EXPRESSION ]
[[ EXPRESSION ]]

如果希望脚本具有可移植性,则应首选使用旧的测试 '[ ' 命令,该命令在所有POSIX Shell上均可用。
使用Bash,Zsh和Ksh作为默认Shell的大多数现代系统均支持测试命令'[[“(双括号)的新升级版本。

检查文件是否存在

检查文件是否存在时,最常用的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/; }

与“ &&”相反,“ ||”后面的语句仅当测试命令的退出状态为'false'时,才执行operator。

[ -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."

检查是否存在多个文件

代替使用复杂的嵌套if/else构造,我们可以使用'-a'(或者'&&'和'[['))来测试是否存在多个文件:

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。