在 Linux 或类 Unix 操作系统下,如何检查 shell 脚本中的目录是否存在?如何在类 Unix 系统上的 shell 脚本中检查目录是否存在?
要检查某个目录是否存在于 shell 脚本中并且是一个目录,请使用以下语法:
## `-d` 测试命令选项查看 FILE 是否存在并且是一个目录 ## [ -d "/path/to/dir" ] && echo "Directory /path/to/dir contains." ## 或者 ## [ ! -d "/path/to/dir" ] && echo "目录 /path/to/dir 不存在。" ## 或者将它们组合在一起: ## [ -d "/path/to/dir" ] && echo "目录 /path/to/dir 存在。" || echo “错误:目录/path/to/dir不存在。”
让我们细分[ -d "/path/to/dir" ] && echo "目录 /path/to/dir 存在。" 句法:
- [ – 这是测试命令条件的开始。
- -d – 这是对目录的测试。
- “/path/to/dir” – 这是我正在测试的目录的路径。
- ] – 这是测试命令条件的结束。
- && – 这是“and”运算符(见下文)。
- echo“目录/path/to/dir存在。” – 如果目录存在,我们将使用 echo 命令显示此消息
请注意[ ! -d "/path/to/dir" ] && echo "目录 /path/to/dir 不存在。" 命令:
- 这[ !-d "/path/to/dir" ]命令的一部分是对目录的测试。
- 这!运算符否定测试,因此这会测试文件/目录是否不存在或不是目录。
- &&运算符的意思是“和”。因此,如果使用 echo 命令目录不存在,整个命令只会显示消息。
教程详情 | |
---|---|
难度级别 | 简单的 |
根权限 | 不 |
要求 | Linux 或 Unix 终端 |
类别 | Linux shell 脚本 |
操作系统兼容性 | BSD • Linux • macOS • Unix |
美东时间。阅读时间 | 3分钟 |
测试命令选项
请记住,当我们说“FILE”时,它也意味着目录。Linux 和 Unix 中一切都是文件。
使用以下命令检查文件/目录类型并比较值:
- -L "FILE": FILE存在并且是一个符号链接(与-h相同)
- -h "FILE" : FILE exists and is a symbolic link (same as -L)
- -d "FILE" : FILE exists and is a directory
- -w "FILE" : FILE exists and write permission is granted
- -x "FILE" : FILE exists and execute (or search) permission is granted
- -r "FILE" : FILE exists and read permission is granted
- -s "FILE" : FILE exists and has a size greater than zero
Checking If a Directory Exists In a Bash Shell Script
The following version also check for symbolic link (-L and -h) :
[ -d "/path/to/dir" ] && [ ! -L "/path/to/dir" ] && echo "Directory /path/to/dir exists." || echo "Error: Directory /path/to/dir exists but point to $(readlink -f /path/to/dir)." ## OR ## [ -d "/path/to/dir" ] && [ ! -h "/path/to/dir" ] && echo "Directory /path/to/dir exists." || echo "Error: Directory /path/to/dir exists but point to $(readlink -f /path/to/dir)."
The && is AND list operator. The syntax is:
$ foo && bar
The bar command is executed if, and only if, foo returns an exit status of zero (success). Similarly we have the || (OR) list and the syntax is:
$ cmd1 || cmd2
The cmd2 is executed if, and only if, cmd1 returns a non-zero exit status. The return status of AND and OR lists is the exit status of the last command executed in the list. You display command exit status using the $? shell variable:
$ date
$ echo $? #<-- show `date` command exit status
In other words, you can now do:
$ date && echo "date command successfully executed."
$ date || echo "date command failed."
# note the typo, the `date` is typed as `date1`
$ date1 || echo "date command failed."
You can combine both conditions as follows:
$ date && echo "Success" || echo "Failed"
OR
$ [ ! -d "/etc/" ] && echo "Not Found" || echo "Found."
Using if..else..if
Finally, you can use the traditional if..else..fi bash syntax as follows:
if [ -d "/path/to/dir" ] then echo "Directory /path/to/dir exists." else echo "Error: Directory /path/to/dir does not exists." fi
OR
### Check if a directory does not exist ### if [ ! -d "/path/to/dir" ] then echo "Directory /path/to/dir DOES NOT exists." exit 9999 # die with error code 9999 fi
Shell script examples to see if a ${directory} exists or not
The following script also demos the use of readlink command to print value of a symbolic link or canonical file name.
#!/bin/bash # dirtest.bash - Demo script by example under GPL v2.x+ # ------------------------------------------------------- dir="$1" [ $# -eq 0 ] && { echo "Usage: $0 dir-name"; exit 1; } if [ -d "$dir" -a ! -h "$dir" ] then echo "$dir found and setting up new Apache/Lighttpd/Nginx jail, please wait..." # __WWWJailSetup "example.com" "setup" else echo "Error: $dir not found or is symlink to $(readlink -f ${dir})." fi
Save and run it your .bash/.sh script as follows:
$ chmod +x dirtest.bash
$ ./dirtest.bash
$ ./dirtest.bash /home/httpd
$ ./dirtest.bash /etc/
$ ./dirtest.bash /nonexiststancedir1
$ ./dirtest.bash /var/www
Sample outputs:
In this example, create directories if does not exists:
# Purpose: Setup jail and copy files # Author: example <www.example.com> under GPL v2.x+ # Category : Core # Override : No # Parameter(s) : d => domain name # action => setup or update __WWWJailSetup(){ local d="$1" local action="${2:setup}" # setup or update??? local index="<html><head><title>$d</title></head><body><h2>$d</h2></body></html>" # default index.html local J="$(_getJailRoot $d)/$d" # our sweet home local _i="" [ "$action" == "setup" ] && echo "* Init jail config at $J..." || echo "* Updating jail init config at $J..." __init_domain_config "$d" [ " $action " == "setup" ] && echo "* 在 $J设置监狱..." || echo "* 正在$J更新监狱..." [ ! -d “ $J ” ] && $_mkdir -p “ $J ” 对于$J / { etc,tmp,usr,var,home,dev,bin,lib64 }中的 _i执行[ ! -d " $_i " ] && $_mkdir -p " $_i "在$_lighttpd_webalizer_base / $d / stats / { dump,out }中为_i完成[ ! -d " $_i " ] && $_mkdir -p " $_i "在$_lighttpd_webalizer_prepost_base / $d / { pre.d ,post.d }中为_i完成[ ! -d " $_i " ] && $_mkdir -p " $_i "完成## 截断}
结论
我们学习了如何在 Linux/Unix bash 下使用 test 命令和其他方法检查 shell 脚本中的目录是否存在。有关详细信息,请参阅以下资源:
以及:
$ man test
$ man bash
$ man readlink
$ man stat
- 来自 Linux shell 脚本 wiki 的文件属性比较。
- Linux/UNIX:查找 Bash shell 中是否存在文件