Vérifier si le répertoire existe en utilisant le caractère home (~) dans bash échoue

16

Pourquoi les éléments suivants bashvérifient-ils si un répertoire échoue?

if [ ! -d "~/Desktop" ]; then
   echo "DOES NOT EXIST"
   exit 1;
fi

~/Desktopexiste bel et bien. C'est d'ailleurs sur un Mac.


Le problème est avec ce type de script

read -p "Provide the destination directory: " DESTINATION

if [ ! -d $DESTINATION ]; then
    echo "\t'$DESTINATION' does not exist." >&2;
    exit 1;
fi
Justin
la source
1
Tout comme lorsque vous le faites, cd "~/Desktop"vous obtenez également une erreur. Il doit être non cité ou stocké sous forme de variable (sans guillemets). Par exemple, a=~/Desktop; cd $a;fonctionne mais pas a="~/Desktop"; cd Desktop;Voir serverfault.com/questions/417252/…
dylnmc

Réponses:

7

Justin a clarifié sa question dans son premier commentaire sur la réponse de quanta. Il lit dans une ligne de texte en utilisant read(ou par un autre moyen dynamique) et souhaite développer le tilde.

La question devient "Comment effectuez-vous l'expansion du tilde sur le contenu d'une variable?"

L'approche générale est à utiliser eval, mais elle comporte quelques mises en garde importantes, à savoir les espaces et la redirection de sortie ( >) dans la variable. Les éléments suivants semblent fonctionner pour moi:

read -p "Provide the destination directory: " DESTINATION

if [ ! -d "`eval echo ${DESTINATION//>}`" ]; then
    echo "'$DESTINATION' does not exist." >&2;
    exit 1;
fi

Essayez-le avec chacune des entrées suivantes:

~
~/existing_dir
~/existing dir with spaces
~/nonexistant_dir
~/nonexistant dir with spaces
~/string containing > redirection
~/string containing > redirection > again and >> again

Explication

  • Le ${mypath//>}supprime les >caractères qui pourraient encombrer un fichier pendant le eval.
  • C'est eval echo ...ce que fait l'expansion réelle du tilde
  • Les guillemets doubles autour du evalsont pour la prise en charge des noms de fichiers avec des espaces.

En complément de cela, vous pouvez améliorer l'UX en ajoutant l' -eoption de lire:

read -p "Provide the destination directory: " -e DESTINATION

Maintenant, lorsque l'utilisateur tape tilde et frappe l'onglet, il se développera. Cependant, cette approche ne remplace pas l'approche eval ci-dessus, car l'expansion ne se produit que si l'utilisateur accède à l'onglet. S'il tape simplement ~ / foo et frappe enter, il restera comme un tilde.

Voir également:

Noach Magedman
la source
23

Supprimez les guillemets doubles dans le répertoire pour voir si cela fonctionne:

if [ ! -d ~/Desktop ]; then
   echo "DOES NOT EXIST"
   exit 1;
fi

La raison en est que l'extension tilde ne fonctionne que lorsqu'elle n'est pas citée.

info "(bash) Tilde Expansion"

3.5.2 Tilde Expansion
---------------------

If a word begins with an unquoted tilde character (`~'), all of the
characters up to the first unquoted slash (or all characters, if there
is no unquoted slash) are considered a TILDE-PREFIX.  If none of the
characters in the tilde-prefix are quoted, the characters in the
tilde-prefix following the tilde are treated as a possible LOGIN NAME.
If this login name is the null string, the tilde is replaced with the
value of the `HOME' shell variable.  If `HOME' is unset, the home
directory of the user executing the shell is substituted instead.
Otherwise, the tilde-prefix is replaced with the home directory
associated with the specified login name.
quanta
la source
Et si la valeur venait dynamiquement. C'est à dire ( pastie.org/4471350 ) et DESTINATIONest ~/Desktop.
Justin
3
L'expansion de tilde se fait lorsque la variable est définie, pas lorsqu'elle est évaluée, donc ce n'est pas un bon exemple.
MadHatter
+1, cela suffit pour résoudre mon problème.
Flying Fisher du
1

courir

echo $HOME

utiliser $HOMEet assurez-vous que l'utilisateur utilise réellement le script. si root utilise ~sa va chercher /root, non /home/$USER.

if [ ! -d "$HOME/Desktop" ]; then
   echo "DOES NOT EXIST"
   exit 1;
fi
trois six
la source
-1
if [ ! -d "$HOME/Desktop" ]; then
   echo "DOES NOT EXIST"
   exit 1;
fi

devrait être $ HOME au lieu de ~

~ est une chose CLAVIER

LeoChu
la source
Si vous lisez l'autre réponse ici, vous vous rendrez compte que c'est faux.
poussins