web-dev-qa-db-fra.com

Bash pour vérifier si le répertoire existe. Sinon créer avec un tableau

Je veux écrire un script Bash, qui vérifie si tous les répertoires, stockés dans un tableau, existent. Sinon, le script devrait le créer. Est-ce une bonne façon de procéder?

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

Vous devez boucler dans votre tableau, alors je proposerais, en 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

Utilisez simplement:

mkdir -p -- "${array1[@]}"

Cela créera également des composants de répertoire intermédiaires si besoin est afin que votre tableau puisse également être raccourci pour inclure uniquement les répertoires feuilles:

array1=(
  /Apache/bin
  /Apache/conf
  /Apache/lib
  /www/html
  /www/cgi-bin
  /www/ftp
)

Que vous pourriez également écrire:

array1=(
  /Apache/{bin,conf,lib}
  /www/{html,cgi-bin,ftp}
)

Le [[ -d ... ]] || mkdir ... le type d'approches introduit en général conditions de course TOCTO et il vaut mieux les éviter autant que possible (bien que dans ce cas particulier il est peu probable que ce soit un problème).

54

Je voudrais développer la réponse fournie par @darxmurf.

Pour ceux qui apprennent simplement les scripts Linux ou Shell, je tiens à souligner que
mkdir /path1/path2/path3 peut ne pas faire exactement ce que vous voulez.
Je suggérerais d'ajouter chown, chmod et sort au script.

Si /path1/path2 n'existe pas, mkdir /path1/path2/path3 échouera.
Cela peut être quelque peu corrigé par
mkdir -p /path1/path2/path3

Dans ce cas, les 3 chemins seront créés avec l'UID, le GID et l'UMASK de l'utilisateur exécutant la commande. Si l'UMASK de l'utilisateur est 077, vous pourriez vous retrouver avec:
mkdir -m 777 -p /path1/path2/path3
vos répertoires ressembleront alors à ceci:

drwx------ /path1
drwx------ /path2
drwxrwxrwx /path3

Ce n'est pas ce que tu veux.

L'utilisation de sort ordonnera d'abord les chemins les plus courts. Considérez un tableau de:
/Apache/bin/cache /Apache /Apache/bin
Vraiment, vous voudriez que le tableau soit:
/Apache /Apache/bin /Apache/bin/cache

Mon premier changement suggéré serait:

array=(
/Apache
/Apache/bin
/Apache/conf
/Apache/lib
/www
/www/html
/www/cgi-bin
/www/ftp
)
array1=$( echo "${array[@]}" | tr ' ' '\n' | sort )

Cela garantira que les répertoires de niveau supérieur apparaîtront avant les niveaux inférieurs.

Le prochain changement que je ferais est le -m pour le mode. Cela garantira que les autorisations que vous souhaitez sont définies sur le répertoire:
mkdir -m ${mode} ${dir}

Définition du propriétaire et du groupe (en particulier s'il s'exécute en tant que root). Si vous êtes membre de GroupA et GroupB, la commande mkdir définira le propriétaire du groupe sur votre groupe par défaut (le premier groupe qui s'affiche sur une commande id). Donc: [[ ! -d "$dir" ]] && mkdir -m ${mode} "$dir" && chown ${user}:${group} "${dir}"

1
Scottie H