Cum pot spune dacă un fișier obișnuit nu există în Bash?

voturi
2k

Am folosit următorul script pentru a vedea dacă există un fișier:

#!/bin/bash

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

Care este sintaxa corectă dacă vreau doar pentru a verifica dacă fișierul nu nu există?

#!/bin/bash

FILE=$1     
if [ $FILE does not exist ]; then
   echo File $FILE does not exist.
fi
Întrebat 12/03/2009 la 13:48
sursa de către utilizator
În alte limbi...                            


19 răspunsuri

voturi
3k

Test de comandă ( [aici) are un „nu“ , operatorul logic , care este punctul de exclamație (similar cu multe alte limbi). Incearca asta:

if [ ! -f /tmp/foo.txt ]; then
    echo "File not found!"
fi
Publicat 12/03/2009 la 13:50
sursa de către utilizator

voturi
246

Puteți nega o expresie cu „!“:

#!/bin/bash
FILE=$1

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

Pagina de om este relevant man testsau, echivalent, man [- sau help testsau help [pentru comanda bash built-in.

Publicat 12/03/2009 la 13:50
sursa de către utilizator

voturi
107
[[ -f $FILE ]] || printf '%s does not exist!\n' "$FILE"

De asemenea, este posibil ca fișierul este un link rupt simbolic, sau un fișier care nu este regulat, cum ar fi de exemplu o priză, dispozitiv sau FIFO. De exemplu, pentru a adăuga un control pentru legături simbolice rupte:

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
Publicat 12/03/2009 la 13:52
sursa de către utilizator

voturi
79

Este demn de menționat faptul că, dacă aveți nevoie pentru a executa o singură comandă, puteți abrevia

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

la

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

sau

[ -f "$file" ] || echo "$file"
Publicat 11/08/2011 la 08:15
sursa de către utilizator

voturi
55

Prefer să fac următoarele o singură linie, în POSIX format compatibil coajă:

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

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

Pentru un cuplu de comenzi, cum aș face într-un script:

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

Odată ce am început să fac acest lucru, eu folosesc rar sintaxa complet tastat mai !!

Publicat 18/10/2011 la 15:09
sursa de către utilizator

voturi
28

Ar trebui să fie atent cu privire la rularea testpentru o variabilă necitate, deoarece s - ar putea produce rezultate neașteptate:

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

Recomandarea este de obicei pentru a avea variabila testată înconjurată de ghilimele duble:

#!/bin/sh
FILE=$1

if [ ! -f "$FILE" ]
then
   echo "File $FILE does not exist."
fi
Publicat 24/01/2012 la 17:43
sursa de către utilizator

voturi
7

testLucru poate conta prea. Ea a lucrat pentru mine (bazat pe Bash Shell: Verificați fișierul există sau nu ):

test -e FILENAME && echo "File exists" || echo "File doesn't exist"
Publicat 31/03/2013 la 12:22
sursa de către utilizator

voturi
7

Pentru a inversa un test, utilizați "!". Aceasta este echivalent cu „nu“, operatorul logic în alte limbi. Incearca asta:

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

Sau scris într-un mod puțin diferit:

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

Sau ai putea folosi:

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

Sau, presing toate împreună:

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

Care poate fi scrisă (folosind apoi „și“ operator de: &&) ca:

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

Ceea ce arata mai scurt ca acest lucru:

[ -f /tmp/foo.txt ] || echo "File not found!"
Publicat 04/05/2013 la 21:29
sursa de către utilizator

voturi
2

Acest script de shell funcționează, de asemenea, pentru a găsi un fișier într-un director:

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
Publicat 29/08/2013 la 05:59
sursa de către utilizator

voturi
35

Pentru a testa existența fișierului, parametrul poate fi oricare dintre următoarele:

-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

Toate testele de mai jos se aplică fișiere regulate, directoare și legături simbolice:

-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

Exemplu de script:

#!/bin/bash
FILE=$1

if [ -f "$FILE" ]; then
   echo "File $FILE exists"
else
   echo "File $FILE does not exist"
fi
Publicat 19/12/2013 la 10:47
sursa de către utilizator

voturi
393

Testarea Bash fișier

-b filename- Bloc fișier special
-c filename- fișier de caractere speciale
-d directoryname- Verificați pentru directorul Existență
-e filename- Verificați existența fișierului, indiferent de tipul (nod, director, soclu, etc.)
-f filename- Verificați existența fișier obișnuit nu este un director
-G filename- Verificați dacă fișierul există și este deținut de ID - ul de grup eficient
-G filename set-group-id- Adevărat dacă fișierul există și este set-group-id
-k filename- sticky bit
-L filename- link simbolic
-O filename- Adevarat daca fisier exista si este proprietatea UID efectiv
-r filename- Verificați dacă fișierul este un ușor de citit
-S filename- Verificați dacă fișierul este socket
-s filename- Verificați dacă fișier este dimensiunea nenul
-u filename- Verificați dacă fișierul set-user-id bit este setat
-w filename- Verificați dacă fișierul este inscriptibil
-x filename- Verificați dacă fișierul este executabil

Cum să utilizați:

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

O expresie de test poate fi negată folosind !operatorul

#!/bin/bash
file=./file
if [ ! -e "$file" ]; then
    echo "File does not exist"
else 
    echo "File exists"
fi 
Publicat 16/01/2014 la 12:25
sursa de către utilizator

voturi
4

Cel mai simplu mod

FILE=$1
[ ! -e "${FILE}" ] && echo "does not exist" || echo "exists"
Publicat 21/05/2014 la 05:11
sursa de către utilizator

voturi
11

Poți sa faci asta:

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

sau

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

Dacă doriți să verificați pentru fișiere și foldere ambele, apoi utilizați -eopțiunea în loc -f. -ereturnează true pentru fișiere regulate, directoare, soclu, fișiere de caractere speciale, fișiere speciale bloc etc.

Publicat 28/04/2015 la 18:40
sursa de către utilizator

voturi
6

Acest cod, de asemenea, de lucru.

#!/bin/bash
FILE=$1
if [ -f $FILE ]; then
 echo "File '$FILE' Exists"
else
 echo "The File '$FILE' Does Not Exist"
fi
Publicat 03/07/2015 la 07:39
sursa de către utilizator

voturi
17

Există trei moduri distincte de a face acest lucru:

  1. Priveze starea de iesire cu bash (nici un alt răspuns a spus acest lucru):

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

    Sau:

    ! [ -e "$file" ] && echo "file does not exist"
    
  2. Priveze testul din interiorul comanda de test [(care este modul în care cele mai multe răspunsuri înainte de a fi prezentat):

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

    Sau:

    [ ! -e "$file" ] && echo "file does not exist"
    
  3. Legea privind rezultatul testului fiind negativ ( în ||loc de &&):

    Numai:

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

    Acest lucru pare o prostie (OMI), nu - l utilizați cu excepția cazului în codul dvs. trebuie să fie portabil la shell - ul Bourne (cum ar fi /bin/shSolaris 10 sau mai devreme) , care nu aveau operatorul conductei negație ( !):

    if [ -e "$file" ]; then
        :
    else
        echo "file does not exist"
    fi
    
Publicat 05/08/2015 la 17:10
sursa de către utilizator

voturi
11

În

[ -f "$file" ]

[comanda nu a stat()(nu lstat()) apel de sistem pe calea stocată în $fileși returnează true dacă acel apel sistem reușește și tipul de fișier returnat de către stat()este „obișnuit“.

Deci , dacă se [ -f "$file" ]întoarce adevărat, vă pot spune fișierul există și este un fișier obișnuit sau o legătură simbolică în cele din urmă rezolvarea într - un fișier obișnuit (sau cel puțin a fost la momentul stat()).

Cu toate acestea , dacă returnează false (sau dacă [ ! -f "$file" ]sau ! [ -f "$file" ]return true), există mai multe posibilități diferite:

  • fișierul nu există
  • fișierul există, dar nu este un fișier obișnuit
  • fișierul există, dar nu aveți permisiunea de căutare în directorul părinte
  • fișierul există, dar această cale să-l acces este prea lung
  • fișierul este o legătură simbolică la un fișier obișnuit, dar nu aveți permisiunea de căutare la unele dintre directoarele implicate în rezoluția symlink.
  • ... orice alt motiv pentru care stat()apelul de sistem poate să nu reușească.

Pe scurt, ar trebui să fie:

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

Pentru a ști sigur că fișierul nu există, am nevoie de stat()apelul de sistem pentru a reveni cu un cod de eroare de ENOENT( ENOTDIRne spune una dintre componentele de cale nu este un director este un alt caz în care putem spune fișierul nu există prin această cale). Din păcate, [comanda nu să ne spui asta. Se va reveni fals dacă codul de eroare este ENOENT, EACCESS (permisiune negat), ENAMETOOLONG sau orice altceva.

[ -e "$file" ]Testul se poate face cu ls -Ld -- "$file" > /dev/null. În acest caz, lsvă va spune de ce a stat()eșuat, deși informațiile nu pot fi utilizate cu ușurință în mod programatic:

$ 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

Cel puțin lsîmi spune că nu este pentru că fișierul nu există că acesta eșuează. Este pentru că nu se poate spune dacă fișierul există sau nu. [Comanda doar ignorat problema.

Cu zshcoajă, puteți interoga codul de eroare cu $ERRNOvariabila specială după lipsa [comenzii, și decoda acel număr utilizând $errnosmatrice specială în zsh/systemmodulul:

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

(ai grijă $errnossuportul este rupt cu unele versiuni ale zshatunci când a construit cu versiuni recente alegcc ).

Publicat 14/10/2016 la 14:18
sursa de către utilizator

voturi
1

uneori poate fi la îndemână pentru a utiliza && și || operatori.

Ca și în (dacă aveți comanda „test“):

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

sau

test -b $FILE || echo File there!
Publicat 11/04/2017 la 19:25
sursa de către utilizator

voturi
0

De asemenea, puteți grupa mai multe comenzi în singură linie

[ -f "filename" ] || ( echo test1 && echo test2 && echo test3 )

sau

[ -f "filename" ] || { echo test1 && echo test2 && echo test3 ;}

Dacă numele de fișier nu iese, ieșirea va fi

test1
test2
test3

Notă: (...) se execută într-un subshell, {...;} se execută în același shell. Notația Acoladă funcționează doar bash.

Publicat 12/06/2019 la 13:50
sursa de către utilizator

voturi
0

Dacă doriți să utilizați „test“ în loc de „[]“, atunci puteți folosi „!“ pentru a obține negației: if ! test "$FILE"; then echo "does not exist" fi

Publicat 27/08/2019 la 21:45
sursa de către utilizator

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more