Comment puis-je savoir si un fichier régulier n'existe pas dans Bash?

J'ai utilisé le script suivant pour voir si un fichier existe:

#!/bin/bash

FILE=$1     
if [ -f $FILE ]; then
   echo "File $FILE exists."
else
   echo "File $FILE does not exist."
fi

Quelle est la syntaxe correcte à utiliser si je veux seulement vérifier si le fichier n'existe pas ?

#!/bin/bash

FILE=$1     
if [ $FILE does not exist ]; then
   echo "File $FILE does not exist."
fi
2612
demandé sur codeforester 2009-03-12 17:48:43

17 réponses

La commandetest ([ ici) a un opérateur logique " not " qui est le point d'exclamation (similaire à beaucoup d'autres langues). Essayez ceci:

if [ ! -f /tmp/foo.txt ]; then
    echo "File not found!"
fi
3656
répondu John Feminella 2014-06-13 14:55:36

Test De Fichier Bash

-b filename - bloquer le fichier spécial
-c filename - Fichier de caractères spéciaux
-d directoryname - Vérifier l'Existence du répertoire
-e filename - Vérifiez l'existence du fichier, quel que soit le type (nœud, répertoire, socket, etc.)
-f filename - Vérifiez l'existence d'un fichier régulier pas un répertoire
-G filename - vérifiez si le fichier existe et appartient à l'ID de groupe effectif
-G filename set-group-id - True si le fichier existe et est set-group-id
-k filename - peu collant
-L filename - lien symbolique
-O filename - Vrai si fichier existe et est détenue par l'uid effectif
-r filename - Vérifier si le fichier est lisible
-S filename - Vérifier si le fichier est prise
-s filename - Vérifier si le fichier est différent de zéro taille
-u filename - Vérifier si le fichier set-user-id bit est défini
-w filename - Vérifier si le fichier est accessible en écriture
-x filename - Vérifier si le fichier est exécutable

Comment utiliser:

#!/bin/bash
file=./file
if [ -e "$file" ]; then
    echo "File exists"
else 
    echo "File does not exist"
fi 

Une expression de test peut être annulée à l'aide de l'opérateur !

#!/bin/bash
file=./file
if [ ! -e "$file" ]; then
    echo "File does not exist"
else 
    echo "File exists"
fi 
456
répondu BlueCacti 2016-07-08 16:02:43

, Vous pouvez annuler une expression avec "!":

#!/bin/bash
FILE=$1

if [ ! -f "$FILE" ]
then
    echo "File $FILE does not exist"
fi

La man page man test ou, de manière équivalente, man [ -- ou help test ou help [ pour de l'intégré dans la commande bash.

254
répondu starbeamrainbowlabs 2017-07-07 10:43:13
[[ -f $FILE ]] || printf '%s does not exist!\n' "$FILE"

En outre, il est possible que le fichier soit un lien symbolique brisé, ou un fichier non régulier, comme par exemple un socket, un périphérique ou un fifo. Par exemple, pour ajouter une vérification des liens symboliques Brisés:

if [[ ! -f $FILE ]]; then
    if [[ -L $FILE ]]; then
        printf '%s is a broken symlink!\n' "$FILE"
    else
        printf '%s does not exist!\n' "$FILE"
    fi
fi
111
répondu guns 2014-09-14 01:41:08

Il convient de mentionner que si vous avez besoin d'exécuter une seule commande, vous pouvez abréger

if [ ! -f "$file" ]; then
    echo "$file"
fi

À

test -f "$file" || echo "$file"

Ou

[ -f "$file" ] || echo "$file"
81
répondu Elazar Leibovich 2014-09-14 01:44:56

Je préfère faire le One-liner suivant, au format compatiblePOSIX shell:

$ [ -f "/$DIR/$FILE" ] || echo "$FILE NOT FOUND"

$ [ -f "/$DIR/$FILE" ] && echo "$FILE FOUND"

Pour quelques commandes, comme je le ferais dans un script:

$  [ -f "/$DIR/$FILE" ] || { echo "$FILE NOT FOUND" ; exit 1 ;}

Une fois que j'ai commencé à faire cela, j'utilise rarement la syntaxe entièrement typée!!

57
répondu J. M. Becker 2015-04-15 07:34:56

Pour tester l'existence du fichier, le paramètre peut être l'une des suivantes:

-e: Returns true if file exists (regular file, directory, or symlink)
-f: Returns true if file exists and is a regular file
-d: Returns true if file exists and is a directory
-h: Returns true if file exists and is a symlink

Tous les tests ci-dessous s'appliquent aux fichiers, répertoires et liens symboliques:

-r: Returns true if file exists and is readable
-w: Returns true if file exists and is writable
-x: Returns true if file exists and is executable
-s: Returns true if file exists and has a size > 0

Exemple de script:

#!/bin/bash
FILE=$1

if [ -f "$FILE" ]; then
   echo "File $FILE exists"
else
   echo "File $FILE does not exist"
fi
37
répondu SD. 2017-01-11 04:32:00

Vous devez faire attention à l'exécution de test pour une variable non cotée, car elle peut produire des résultats inattendus:

$ [ -f ]
$ echo $?
0
$ [ -f "" ]
$ echo $?
1

La recommandation est généralement d'avoir la variable testée entourée de guillemets doubles:

#!/bin/sh
FILE=$1

if [ ! -f "$FILE" ]
then
   echo "File $FILE does not exist."
fi
28
répondu artdanil 2015-04-15 07:35:31

Il y a trois façons distinctes de le faire:

  1. Annule le statut de sortie avec bash (aucune autre réponse n'a dit Cela):

    if ! [ -e "$file" ]; then
        echo "file does not exist"
    fi
    

    Ou:

    ! [ -e "$file" ] && echo "file does not exist"
    
  2. Annule le test dans la commande de test [ (c'est la façon dont la plupart des réponses ont été présentées auparavant):

    if [ ! -e "$file" ]; then
        echo "file does not exist"
    fi
    

    Ou:

    [ ! -e "$file" ] && echo "file does not exist"
    
  3. Agir sur le résultat du test étant négatif (|| au lieu de &&):

    Seulement:

    [ -e "$file" ] || echo "file does not exist"
    

    Cela semble stupide (IMO), ne le faites pas utilisez-le sauf si votre code doit être portable dans le shell Bourne (comme le /bin/sh de Solaris 10 ou plus tôt) qui manquait l'opérateur de négation de pipeline(!):

    if [ -e "$file" ]; then
        :
    else
        echo "file does not exist"
    fi
    
18
répondu Stephane Chazelas 2016-10-14 21:20:16

, Vous pouvez faire ceci:

[[ ! -f "$FILE" ]] && echo "File doesn't exist"

Ou

if [[ ! -f "$FILE" ]]; then
    echo "File doesn't exist"
fi

Si vous voulez vérifier le fichier et le dossier à la fois, utilisez l'option -e au lieu de -f. -e renvoie true pour les fichiers réguliers, les répertoires, les sockets, les fichiers spéciaux de caractères,les fichiers spéciaux de blocs, etc.

18
répondu Jahid 2018-05-09 18:59:18

Dans

[ -f "$file" ]

La commande [ effectue un appel système stat() (Pas lstat()) sur le chemin stocké dans $file et renvoie true si cet appel système réussit et que le type de fichier renvoyé par stat() est "normal".

Donc, si [ -f "$file" ] renvoie true, vous pouvez dire que le fichier existe et qu'il s'agit d'un fichier régulier ou d'un lien symbolique se résolvant éventuellement en un fichier régulier (ou du moins au moment du stat()).

Toutefois, si elle retourne false (ou si [ ! -f "$file" ] ou ! [ -f "$file" ] return true), il y a beaucoup de possibilités différentes:

  • le fichier n'existe pas
  • le fichier existe mais n'est pas un fichier régulier
  • le fichier existe mais vous n'avez pas l'autorisation de recherche dans le répertoire parent
  • le fichier existe mais ce chemin d'accès est trop long
  • le fichier est un lien symbolique vers un fichier normal, mais vous n'avez pas l'autorisation de recherche sur certains des répertoires impliqués dans la résolution du lien symbolique.
  • ... tout autre raison pour laquelle l'appel système stat() peut échouer.

En bref, il devrait être:

if [ -f "$file" ]; then
  printf '"%s" is a path to a regular file or symlink to regular file\n' "$file"
elif [ -e "$file" ]; then
  printf '"%s" exists but is not a regular file\n' "$file"
elif [ -L "$file" ]; then
  printf '"%s" exists, is a symlink but I cannot tell if it eventually resolves to an actual file, regular or not\n' "$file"
else
  printf 'I cannot tell if "%s" exists, let alone whether it is a regular file or not\n' "$file"
fi

Pour savoir avec certitude que le fichier n'existe pas, nous aurions besoin de l'appel système stat() pour revenir avec un code d'erreur de ENOENT (ENOTDIR nous dit que l'un des composants du chemin n'est pas un répertoire est un autre cas où nous pouvons dire que le fichier n'existe pas par ce chemin). Malheureusement, la commande [ ne nous le fait pas savoir. Il retournera false si le code d'erreur est ENOENT, eAccess (permission refusé), ENAMETOOLONG ou toute autre chose.

Le [ -e "$file" ] test peut également être effectué avec ls -Ld -- "$file" > /dev/null. Dans ce cas, ls vous dira Pourquoi le stat() a échoué, bien que l'information ne puisse pas facilement être utilisée par programme:

$ file=/var/spool/cron/crontabs/root
$ if [ ! -e "$file" ]; then echo does not exist; fi
does not exist
$ if ! ls -Ld -- "$file" > /dev/null; then echo stat failed; fi
ls: cannot access '/var/spool/cron/crontabs/root': Permission denied
stat failed

, Au moins ls me dit que c'est pas parce que le fichier n'existe pas, qu'il échoue. C'est parce qu'il ne peut pas dire si le fichier existe ou non. La commande [ a simplement ignoré le problème.

Avec zsh shell, vous pouvez interroger le code d'erreur avec le $ERRNO variable spéciale après la commande [ défaillante, et décoder ce nombre en utilisant le tableau spécial $errnos dans le module zsh/system:

zmodload zsh/system
ERRNO=0
if [ ! -f "$file" ]; then
  err=$ERRNO
  case $errnos[err] in
    ("") echo exists, not a regular file;;
    (ENOENT|ENOTDIR)
       if [ -L "$file" ]; then
         echo broken link
       else
         echo does not exist
       fi;;
    (*) echo "can't tell"; syserror "$err"
  esac
fi

(méfiez-vous du $errnos le support est cassé avec certaines versions de zsh lorsqu'il est construit avec des versions récentes de gcc).

15
répondu Stephane Chazelas 2017-09-20 14:09:58

Pour inverser un test, utilisez "!". C'est équivalent à l'opérateur logique " not " dans d'autres langues. Essayez ceci:

if [ ! -f /tmp/foo.txt ];
then
    echo "File not found!"
fi

Ou écrit d'une manière légèrement différente:

if [ ! -f /tmp/foo.txt ]
    then echo "File not found!"
fi

, Ou vous pouvez utiliser:

if ! [ -f /tmp/foo.txt ]
    then echo "File not found!"
fi

, Ou, presing tous ensemble:

if ! [ -f /tmp/foo.txt ]; then echo "File not found!"; fi

Qui peut être écrit (en utilisant alors " et " opérateur:&&) comme:

[ ! -f /tmp/foo.txt ] && echo "File not found!"

Qui semble plus court comme ceci:

[ -f /tmp/foo.txt ] || echo "File not found!"
7
répondu 2013-05-04 22:29:20

La chose test peut aussi compter. Cela a fonctionné pour moi (basé sur Bash Shell: Vérifier le fichier existe ou non):

test -e FILENAME && echo "File exists" || echo "File doesn't exist"
7
répondu android developer 2013-06-26 17:30:05

Ce code fonctionne également .

#!/bin/bash
FILE=$1
if [ -f $FILE ]; then
 echo "File '$FILE' Exists"
else
 echo "The File '$FILE' Does Not Exist"
fi
7
répondu Lemon Kazi 2015-07-03 08:39:37

Le moyen le plus simple

FILE=$1
[ ! -e "${FILE}" ] && echo "does not exist" || echo "exists"
5
répondu lancerex 2015-08-01 01:35:00

Ce script shell fonctionne également pour trouver un fichier dans un répertoire:

echo "enter file"

read -r a

if [ -s /home/trainee02/"$a" ]
then
    echo "yes. file is there."
else
    echo "sorry. file is not there."
fi
3
répondu Simmant 2015-08-05 21:01:40

Parfois, il peut être pratique d'utiliser && et || les opérateurs.

Comme dans (Si vous avez la commande "test"):

test -b $FILE && echo File not there!

Ou

test -b $FILE || echo File there!
1
répondu André 2017-04-11 20:25:18