我想编写一个 Bash 脚本,它检查存储在数组中的所有目录是否存在。如果没有,脚本应该创建它。这是正确的方法吗?
array1=(
/apache
/apache/bin
/apache/conf
/apache/lib
/www
/www/html
/www/cgi-bin
/www/ftp
)
if [ ! -d “$array1” ]; then
mkdir $array1
else
break
fi
答案1
只需使用:
mkdir -p -- "${array1[@]}"
如果需要的话,这还将创建中间目录组件,因此您的数组也可以缩短为仅包含叶目录:
array1=(
/apache/bin
/apache/conf
/apache/lib
/www/html
/www/cgi-bin
/www/ftp
)
你也可以这样写:
array1=(
/apache/{bin,conf,lib}
/www/{html,cgi-bin,ftp}
)
[[ -d ... ]] || mkdir ...
一般介绍的方法类型TOCTOU 比赛条件并且最好尽可能避免(尽管在这种特殊情况下这不太可能成为问题)。
答案2
你必须在你的数组中循环,然后我建议,在 bash 中
array1=(
/apache
/apache/bin
/apache/conf
/apache/lib
/www
/www/html
/www/cgi-bin
/www/ftp
)
for dir in "${array1[@]}"; do
[[ ! -d "$dir" ]] && mkdir "$dir"
done
答案3
我想扩展@darxmurf 提供的答案。
对于那些刚刚学习 Linux 或 shell 脚本编写的人来说,我想指出这
mkdir /path1/path2/path3
可能并不完全符合您的要求。
我建议将chown
、chmod
、 和添加sort
到脚本中。
如果/path1/path2
不存在,mkdir /path1/path2/path3
将会失败。
这可以通过以下方式稍微纠正
mkdir -p /path1/path2/path3
在这种情况下,将使用运行命令的用户的 UID、GID 和 UMASK 创建所有 3 个路径。如果用户的 UMASK 是 077,您最终可能会得到:
mkdir -m 777 -p /path1/path2/path3
您的目录将如下所示:
drwx------ /path1
drwx------ /path2
drwxrwxrwx /path3
这不是你想要的。
使用sort
将首先对较短的路径进行排序。考虑一个数组:
/apache/bin/cache /apache /apache/bin
实际上,您希望该数组是:
/apache /apache/bin /apache/bin/cache
我的第一个建议的改变是:
array=(
/apache
/apache/bin
/apache/conf
/apache/lib
/www
/www/html
/www/cgi-bin
/www/ftp
)
array1=$( echo "${array[@]}" | tr ' ' '\n' | sort )
这将保证较高级别的目录将在较低级别的目录之前显示。
我要做的下一个更改是-m
for 模式。这将确保在目录上设置您想要的权限:
mkdir -m ${mode} ${dir}
设置所有者和组(特别是如果以 root 身份运行)。如果您是 GroupA 和 GroupB 的成员,则 mkdir 命令会将组所有者设置为您的默认组(命令中显示的第一个组id
)。因此:
[[ ! -d "$dir" ]] && mkdir -m ${mode} "$dir" && chown ${user}:${group} "${dir}"