Bash中如何检查是否存在文件或者目录
很多时候编写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。