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
if [ -f $FILE ]; then; else; echo "File $FILE does not exist."; fi;
Probablement bien que j'ai trouvé cette question à la place et appris à le faire de manière plus appropriée. :)-e
. -f ne ramasse pas les répertoires, les liens symboliques, etc.FILE=$1
->FILE="$1"
etif [ -f $FILE ];
->if [ -f "$FILE" ];
Réponses:
La commande de test (
[
ici) a un opérateur logique "non" qui est le point d'exclamation (similaire à de nombreuses autres langues). Essaye ça:la source
if [ ! \( -f "f1" -a -f "f2" \) ] ; then echo MISSING; fi
if [ ! -f "f1" ] || [ ! -f "f2" ] ; then echo MISSING; fi
[ -f /tmp/foo.txt ] || echo "File not found!"
-e: Returns true value, if file exists
-f: Return true value, if file exists and regular file
-r: Return true value, if file exists and is readable
-w: Return true value, if file exists and is writable
-x: Return true value, if file exists and is executable
-d: Return true value, if exists and is a directory
! -f
avec&&
et l'utilisation-f
avec||
. Cela a à voir avec le code de sortie renvoyé par la vérification de non / existence. Si vous avez besoin que votre ligne quitte toujours proprement avec le code de sortie 0 (et parfois vous ne voulez pas de cette contrainte), les deux approches ne sont pas interchangeables. Alternativement, utilisez simplement uneif
instruction et vous n'aurez plus à vous soucier du code de sortie de votre contrôle de non / existence.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érifier l'existence du fichier, quel que soit le type (nœud, répertoire, socket, etc.)-f filename
- Vérifier l'existence régulière du fichier et non un répertoire-G filename
- Vérifier si le fichier existe et appartient à ID de groupe effectif-G filename set-group-id
- Vrai si le fichier existe et est défini-group-id-k filename
- Sticky bit-L filename
- Lien symbolique-O filename
- Vrai si le fichier existe et appartient à l'ID utilisateur effectif-r filename
- Vérifiez si le fichier est lisible-S filename
- Vérifiez si le fichier est socket-s filename
- Vérifiez si le fichier est de taille différente de zéro-u filename
- Vérifiez si le fichier set-user-id est défini-w filename
- Vérifiez si le fichier est accessible en écriture-x filename
- Vérifiez si le fichier est exécutableComment utiliser:
Une expression de test peut être annulée à l'aide de l'
!
opérateurla source
-n String
- Vérifiez si la longueur de la chaîne n'est pas nulle. Ou voulez-vous direfile1 -nt file2
- Vérifiez si le fichier1 est plus récent que le fichier 2 (vous pouvez également utiliser -ot pour les anciens)The unary operator -z tests for a null string, while -n or no operator at all returns True if a string is not empty.
~ ibm.com/developerworks/library/l-bash-test/index.htmlVous pouvez annuler une expression avec "!":
La page de manuel appropriée est
man test
ou, de manière équivalente,man [
- ouhelp test
ouhelp [
pour la commande bash intégrée.la source
[
est un builtin. Donc, les informations pertinentes sont plutôt obtenues parhelp [
... mais cela montre que[
c'est un synonyme de la fonctiontest
intégrée, donc les informations pertinentes sont plutôt obtenues parhelp test
. Voir également la section Expression conditionnelle Bash du manuel .[
commande intégrée bash se comporte de manière très similaire à la[
commande externe , donc soitman test
ouman [
vous donnera une bonne idée de son fonctionnement.[
a plus de commutateurs que la commande externe[
trouvé sur mon système ... D'une manière générale , je crois qu'il est préférable de lire la documentation spécifique à un outil donné, et non la documentation spécifique à un autre vaguement connexe. Je me trompe peut-être, cependant;)
En outre, il est possible que le fichier soit un lien symbolique rompu 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 rompus:
la source
Il convient de mentionner que si vous devez exécuter une seule commande, vous pouvez abréger
à
ou
la source
Je préfère faire le one-liner suivant, au format compatible POSIX shell:
Pour quelques commandes, comme je le ferais dans un script:
Une fois que j'ai commencé à le faire, j'utilise rarement la syntaxe entièrement typée !!
la source
[
outest
intégré testerait l' existence de fichier de l'argument par défaut (par opposition à-e
)? Cela ne serait-il pas ambigu? AFAIK (et AIUI la section "EXPRESSIONS CONDITIONNELLES") la seule chose qui est testée avec votre approche est que l'argument n'est pas vide (ou indéfini), qui est, dans ce cas, une tautologie (let$DIR = ''
et$FILE = ''
, alors l'argument est toujours'//'
).ls /foo
résultatls: cannot access /foo: No such file or directory
.[ /foo ] && echo 42
, résultat42
. GNU bash, version 4.2.37 (1) -release (i486-pc-linux-gnu).-f
option, au moment où j'ai écrit cette réponse. Évidemment, vous pouvez toujours utiliser-e
, si vous n'êtes pas sûr que ce sera un fichier normal. De plus, dans tous mes scripts, je cite ces constructions, je dois juste les avoir soumises sans vérification adéquate.[ $condition ] && if_true || if_false
est sujet aux erreurs. Quoi qu'il en soit, je trouve[ ! -f "$file" ] && if_not_exists
plus facile à lire et à comprendre que[ -f "$file" ] || if_not_exists
.Pour tester l'existence du fichier, le paramètre peut être l'un des suivants:
Tous les tests ci-dessous s'appliquent aux fichiers, répertoires et liens symboliques standard:
Exemple de script:
la source
Tu peux le faire:
ou
Si vous souhaitez vérifier le fichier et le dossier à la fois, utilisez l'
-e
option au lieu de-f
.-e
renvoie vrai pour les fichiers, répertoires, socket, fichiers spéciaux de caractères normaux, fichiers spéciaux de bloc, etc.la source
[
utilitaire standard .-f
) et les répertoires ne sont que deux types de fichiers différents . Il existe également des sockets, des liens symboliques, des périphériques, des fifos, des portes ...[ -e
qui testeront l'existence des fichiers (de tout type, y compris regular, fifo, directory ...) après la résolution du lien symbolique .-e
, il a besoin-f
.Vous devez être prudent lors de l'exécution
test
d'une variable sans guillemets, car cela pourrait produire des résultats inattendus:Il est généralement recommandé de placer la variable testée entre guillemets doubles:
la source
[ ... ]
.Il existe trois façons distinctes de procéder:
Annulez le statut de sortie avec bash (aucune autre réponse ne l'a dit):
Ou:
Annulez le test dans la commande test
[
(c'est la façon dont la plupart des réponses ont été présentées auparavant):Ou:
Agir sur le résultat du test négatif (
||
au lieu de&&
):Seulement:
Cela a l'air idiot (IMO), ne l'utilisez pas sauf si votre code doit être portable sur le shell Bourne (comme celui
/bin/sh
de Solaris 10 ou antérieur) qui manquait de l'opérateur de négation du pipeline (!
):la source
! [
et[ !
?! [
s'agit de POSIX pour les pipelines shell 2.9.2 (n'importe quelle commande)Otherwise, the exit status shall be the logical NOT of the exit status of the last command
et de[ !
POSIX pour le test.! expression True if expression is false. False if expression is true.
Donc, les deux sont POSIX, et d'après mon expérience, les deux sont largement pris en charge.!
mot - clé introduit par le shell Korn. Sauf peut-être pour Solaris 10 et les versions antérieures, il est peu probable que vous rencontriez un shell Bourne de nos jours.Dans
la
[
commande effectue unstat()
(paslstat()
) appel système sur le chemin stocké dans$file
et renvoie true si cet appel système réussit et que le type de fichier renvoyé parstat()
est " normal ".Donc, si
[ -f "$file" ]
renvoie true, vous pouvez dire que le fichier existe et qu'il s'agit d'un fichier normal ou d'un lien symbolique qui se résout finalement en un fichier normal (ou du moins c'était au moment de lastat()
).Cependant, si elle renvoie false (ou si
[ ! -f "$file" ]
ou! [ -f "$file" ]
retourne true), il existe de nombreuses possibilités différentes:stat()
appel système peut échouer.Bref, ce devrait être:
Pour savoir avec certitude que le fichier n'existe pas, nous aurions besoin de l'
stat()
appel système pour retourner avec un code d'erreur deENOENT
(ENOTDIR
nous indique que l'un des composants du chemin n'est pas un répertoire est un autre cas où nous pouvons dire que le fichier ne l'est pas exister par ce chemin). Malheureusement,[
commande ne nous le fait pas savoir. Il retournera faux si le code d'erreur est ENOENT, EACCESS (autorisation refusée), ENAMETOOLONG ou autre.Le
[ -e "$file" ]
test peut également être effectué avecls -Ld -- "$file" > /dev/null
. Dans ce cas,ls
vous dira pourquoi l'stat()
échec, bien que les informations ne puissent pas être facilement utilisées par programme:Au moins
ls
me dit que ce n'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 le
zsh
shell, vous pouvez interroger le code d'erreur avec la$ERRNO
variable spéciale après la[
commande en échec et décoder ce nombre à l'aide du$errnos
tableau spécial duzsh/system
module:(attention, le
$errnos
support a été rompu avec certaines versions dezsh
lors de sa construction avec des versions récentes degcc
).la source
Pour inverser un test, utilisez "!". Cela équivaut à l'opérateur logique "non" dans d'autres langues. Essaye ça:
Ou écrit d'une manière légèrement différente:
Ou vous pouvez utiliser:
Ou, en présageant tous ensemble:
Qui peut s'écrire (en utilisant alors l'opérateur "et": &&) comme:
Qui ressemble plus court à ceci:
la source
La
test
chose peut aussi compter. Cela a fonctionné pour moi (basé sur Bash Shell: Vérifier que le fichier existe ou non ):la source
Ce code fonctionne également.
la source
La manière la plus simple
la source
Ce script shell fonctionne également pour trouver un fichier dans un répertoire:
la source
read -p "Enter file name: " -r a
aussi bien pour l'invite que pour la lecture. Il utilise des guillemets autour de la variable; c'est bien, mais devrait être expliqué. Il vaudrait peut-être mieux qu'il répète le nom du fichier. Et cela vérifie que le fichier existe et n'est pas vide (c'est le sens de-s
) alors que la question porte sur n'importe quel fichier, vide ou non (pour lequel-f
est plus approprié).parfois, il peut être utile d'utiliser && et || les opérateurs.
Comme dans (si vous avez la commande "test"):
ou
la source
Si vous souhaitez utiliser à la
test
place de[]
, vous pouvez utiliser!
pour obtenir la négation:la source
Vous pouvez également regrouper plusieurs commandes dans la même ligne
[ -f "filename" ] || ( echo test1 && echo test2 && echo test3 )
ou
[ -f "filename" ] || { echo test1 && echo test2 && echo test3 ;}
Si le nom de fichier ne se ferme pas, la sortie sera
Remarque: (...) s'exécute dans un sous-shell, {...;} s'exécute dans le même shell.
La notation entre accolades ne fonctionne qu'en bash.la source
la source