web-dev-qa-db-ja.com

bashを実行して、ディレクトリが存在するかどうかを確認します。配列で作成しない場合

配列に格納されているすべてのディレクトリが存在するかどうかを確認する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
8
user3573614

あなたはあなたの配列でループする必要があります、そして私は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
11
darxmurf

ただ使用する:

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競合状態 を導入し、可能な限り回避することをお勧めします(この特定のケースでは問題になる可能性は低いです)。

54

@darxmurfが提供する回答について詳しく説明します。

Linuxまたはシェルスクリプトを学習しているだけの人のために、私はそれを指摘したいと思います
mkdir /path1/path2/path3は、期待どおりに動作しない場合があります。
スクリプトにchownchmodsortを追加することをお勧めします。

/path1/path2 存在しません、 mkdir /path1/path2/path3は失敗します。
これは、
mkdir -p /path1/path2/path3

この場合、3つのパスすべてが、コマンドを実行しているユーザーのUID、GID、およびUMASKで作成されます。ユーザーの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モード。これにより、必要な権限がディレクトリに設定されます。
mkdir -m ${mode} ${dir}

所有者とグループを設定します(rootとして実行している場合はesp)。 GroupAおよびGroupBのメンバーである場合、mkdirコマンドはグループ所有者をデフォルトグループ(idコマンドに表示される最初のグループ)に設定します。したがって、[[ ! -d "$dir" ]] && mkdir -m ${mode} "$dir" && chown ${user}:${group} "${dir}"

1
Scottie H