226 votes

Vérifier si l'argument passé est un fichier ou un répertoire dans BASH

Je suis en train d'écrire un extrêmement simple script dans Ubuntu qui me permettrait de passer un nom de fichier ou un répertoire, et être en mesure de faire quelque chose de spécifique quand c'est un fichier, et quelque chose d'autre quand c'est un répertoire. Le problème que je vais avoir, c'est quand le nom du répertoire, ou probablement aussi des fichiers, des espaces ou d'autres escapable de caractères dans le nom.

Voici mon code de base vers le bas ci-dessous, et un couple de tests.

#!/bin/bash

PASSED=$1

if [ -d "${PASSED}" ] ; then
    echo "$PASSED is a directory";
else
    if [ -f "${PASSED}" ]; then
        echo "${PASSED} is a file";
    else
        echo "${PASSED} is not valid";
        exit 1
    fi
fi

Et voici le résultat:

andy@server~ $ ./scripts/testmove.sh /home/andy/
/home/andy/ is a directory

andy@server~ $ ./scripts/testmove.sh /home/andy/blah.txt
/home/andy/blah.txt is a file

andy@server~ $ ./scripts/testmove.sh /home/andy/blah\ with\ a\ space.txt
/home/andy/blah with a space.txt is not valid

andy@server~ $ ./scripts/testmove.sh /home/andy\ with\ a\ space/
/home/andy with a space/ is not valid

Tous ces chemins sont valides, et exister.

298voto

John Kugelman Points 108754

Cela devrait fonctionner. Je ne sais pas pourquoi c'est un échec. Vous citez vos variables correctement. Que se passe-t-il si vous utilisez ce script avec un double [[ ]] ?

 if [[ -d $PASSED ]]; then
    echo "$PASSED is a directory"
elif [[ -f $PASSED ]]; then
    echo "$PASSED is a file"
else
    echo "$PASSED is not valid"
    exit 1
fi
 

Les doubles crochets sont une extension bash à [ ] . Il n’est pas nécessaire de citer des variables, même si elles contiennent des espaces.

Cela vaut également la peine d'essayer: -e pour tester si un chemin existe sans tester le type de fichier.

19voto

Jonathan Leffler Points 299946

Au moins, écrivez le code sans l'arbre touffu:

 #!/bin/bash

PASSED=$1

if   [ -d "${PASSED}" ]
then echo "${PASSED} is a directory";
elif [ -f "${PASSED}" ]
then echo "${PASSED} is a file";
else echo "${PASSED} is not valid";
     exit 1
fi
 

Quand je mets cela dans un fichier "xx.sh" et crée un fichier "xx sh", et l'exécute, je reçois:

 $ cp /dev/null "xx sh"
$ for file in . xx*; do sh "$file"; done
. is a directory
xx sh is a file
xx.sh is a file
$
 

Étant donné que vous rencontrez des problèmes, vous devriez peut-être déboguer le script en ajoutant une ligne:

 ls -l "${PASSED}"
 

Cela vous montrera ce que ls pense des noms que vous transmettez au script.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X