Jak sprawdzić, czy zwykły plik nie istnieje w Bash?
Użyłem następującego skryptu, aby sprawdzić, czy plik istnieje:
#!/bin/bash
FILE=$1
if [ -f $FILE ]; then
echo "File $FILE exists."
else
echo "File $FILE does not exist."
fi
Jaka jest poprawna składnia, jeśli chcę tylko sprawdzić, czy plik nie istnieje?
#!/bin/bash
FILE=$1
if [ $FILE does not exist ]; then
echo "File $FILE does not exist."
fi
17 answers
Polecenie test ([
tutaj) ma operator logiczny" Nie", który jest wykrzyknikiem (podobnie jak wiele innych języków). Spróbuj tego:
if [ ! -f /tmp/foo.txt ]; then
echo "File not found!"
fi
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-06-13 14:55:36
Testowanie Plików Bash
-b filename
- Blokuj plik specjalny-c filename
- Plik znaków specjalnych-d directoryname
- Sprawdź istnienie katalogu-e filename
- Sprawdź istnienie pliku, niezależnie od typu (węzeł, katalog, Gniazdo, itp.)-f filename
- sprawdź, czy zwykły plik nie jest katalogiem-G filename
- Sprawdź, czy plik istnieje i jest własnością efektywnego ID grupy-G filename set-group-id
- True Jeśli plik istnieje i ma identyfikator set-group-id-k filename
- Sticky bit-L filename
- dowiązanie symboliczne-O filename
- True Jeśli plik istnieje i jest własnością efektywnego id użytkownika-r filename
- sprawdź, czy plik jest czytelny-S filename
- sprawdź czy plik jest gniazdem-s filename
- sprawdź, czy plik jest niezerowy-u filename
- sprawdź, czy bit set-user-id jest ustawiony-w filename
- sprawdź, czy plik jest zapisywalny-x filename
- sprawdź czy plik jest wykonywalny
Jak używać:
#!/bin/bash
file=./file
if [ -e "$file" ]; then
echo "File exists"
else
echo "File does not exist"
fi
A wyrażenie testowe można negować za pomocą operatora !
#!/bin/bash
file=./file
if [ ! -e "$file" ]; then
echo "File does not exist"
else
echo "File exists"
fi
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-07-08 16:02:43
Możesz negować wyrażenie przez "!":
#!/bin/bash
FILE=$1
if [ ! -f "$FILE" ]
then
echo "File $FILE does not exist"
fi
Odpowiednią stroną podręcznika jest man test
lub, równoważnie, man [
-- lub help test
lub help [
dla wbudowanego polecenia bash.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-07 10:43:13
[[ -f $FILE ]] || printf '%s does not exist!\n' "$FILE"
Możliwe jest również, że plik jest zepsutym dowiązaniem symbolicznym lub plikiem niestandardowym, takim jak np. Gniazdo, urządzenie lub fifo. Na przykład, aby dodać sprawdzenie pod kątem uszkodzonych dowiązań symbolicznych:
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
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-09-14 01:41:08
Warto wspomnieć, że jeśli trzeba wykonać jedną komendę można skrócić
if [ ! -f "$file" ]; then
echo "$file"
fi
Do
test -f "$file" || echo "$file"
Lub
[ -f "$file" ] || echo "$file"
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-09-14 01:44:56
Wolę wykonać następujące jednolinijkowe, w POSIX formacie zgodnym z powłoką:
$ [ -f "/$DIR/$FILE" ] || echo "$FILE NOT FOUND"
$ [ -f "/$DIR/$FILE" ] && echo "$FILE FOUND"
Za kilka komend, tak jak ja bym zrobił w skrypcie:
$ [ -f "/$DIR/$FILE" ] || { echo "$FILE NOT FOUND" ; exit 1 ;}
Kiedy zacząłem to robić, rzadko używam już w pełni wpisanej składni!!
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-04-15 07:34:56
Aby sprawdzić istnienie pliku, parametr może być dowolny z następujących:
-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
Wszystkie poniższe testy dotyczą zwykłych plików, katalogów i dowiązań symbolicznych:
-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
Przykładowy skrypt:
#!/bin/bash
FILE=$1
if [ -f "$FILE" ]; then
echo "File $FILE exists"
else
echo "File $FILE does not exist"
fi
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-11 04:32:00
Należy uważać na uruchamianie test
dla zmiennej nienotowanej, ponieważ może ona przynieść nieoczekiwane rezultaty:
$ [ -f ]
$ echo $?
0
$ [ -f "" ]
$ echo $?
1
Zaleca się, aby badana zmienna otoczona była podwójnymi cudzysłowami:
#!/bin/sh
FILE=$1
if [ ! -f "$FILE" ]
then
echo "File $FILE does not exist."
fi
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-04-15 07:35:31
Istnieją trzy różne sposoby, aby to zrobić:
-
Neguj status wyjścia za pomocą bash (żadna inna odpowiedź nie powiedziała tego):
if ! [ -e "$file" ]; then echo "file does not exist" fi
Lub:
! [ -e "$file" ] && echo "file does not exist"
-
Odrzuć test wewnątrz polecenia test
[
(tak prezentowało się większość odpowiedzi wcześniej):if [ ! -e "$file" ]; then echo "file does not exist" fi
Lub:
[ ! -e "$file" ] && echo "file does not exist"
-
Działanie na wynik testu negatywny (
||
zamiast&&
):Tylko:
[ -e "$file" ] || echo "file does not exist"
To wygląda głupio (IMO), Nie używaj go, chyba że Twój kod musi być przenośny do powłoki Bourne ' a (jak
/bin/sh
z Solarisa 10 lub wcześniejszego), która nie ma operatora negacji potoków(!
):if [ -e "$file" ]; then : else echo "file does not exist" fi
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-14 21:20:16
Możesz to zrobić:
[[ ! -f "$FILE" ]] && echo "File doesn't exist"
Lub
if [[ ! -f "$FILE" ]]; then
echo "File doesn't exist"
fi
Jeśli chcesz sprawdzić zarówno Plik, jak i folder, użyj opcji -e
zamiast -f
. -e
zwraca true dla zwykłych plików, katalogów, gniazd, specjalnych plików znakowych, blokowych plików specjalnych itp.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-09 18:59:18
W
[ -f "$file" ]
Polecenie [
wykonuje stat()
(Nie lstat()
) wywołanie systemowe na ścieżce przechowywanej w $file
i zwraca true jeśli wywołanie systemowe powiedzie się, A Typ pliku zwracany przez stat()
jest "regularny".
Więc jeśli [ -f "$file" ]
zwróci true, możesz powiedzieć, że plik istnieje i jest zwykłym plikiem lub dowiązaniem symbolicznym, które ostatecznie zostanie rozdzielone na zwykły plik(a przynajmniej było to w czasie stat()
).
Jeśli jednak zwróci false (lub jeśli [ ! -f "$file" ]
lub ! [ -f "$file" ]
return true), istnieje wiele różnych możliwości:
- plik nie istnieje
- plik istnieje, ale nie jest zwykłym plikiem
- plik istnieje, ale nie masz uprawnień do wyszukiwania w katalogu nadrzędnym
- plik istnieje, ale ścieżka dostępu do niego jest zbyt długa
- plik jest dowiązaniem symbolicznym do zwykłego pliku, ale nie masz uprawnień do przeszukiwania niektórych katalogów zaangażowanych w rozdzielczość dowiązania symbolicznego.
- ... dowolne inny powód, dla którego wywołanie systemowe
stat()
może się nie udać.
W skrócie powinno być:
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
Aby mieć pewność, że plik nie istnieje, potrzebujemy wywołania systemowego stat()
, aby powrócić z kodem błęduENOENT
(ENOTDIR
mówi nam, że jeden ze składników path nie jest katalogiem, to kolejny przypadek, w którym możemy stwierdzić, że plik nie istnieje przez tę ścieżkę). Niestety polecenie [
nie daje nam o tym znać. Zwróci false, czy kod błędu jest ENOENT, EACCESS( uprawnienie odmowa), ENAMETOOLONG lub cokolwiek innego.
Test [ -e "$file" ]
można również wykonać za pomocą ls -Ld -- "$file" > /dev/null
. W takim przypadku ls
powie Ci, dlaczego stat()
nie powiodło się, choć informacje nie mogą być łatwo użyte programowo:
$ 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
Przynajmniej ls
mówi mi, że to nie dlatego, że plik nie istnieje, że zawodzi. To dlatego, że nie może stwierdzić, czy plik istnieje, czy nie. Polecenie [
zignorowało problem.
Za pomocą powłoki zsh
można odpytywać kod błędu za pomocą $ERRNO
specjalna zmienna po nieudanym poleceniu [
i dekodowanie tej liczby za pomocą specjalnej tablicy $errnos
w 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
(beware the $errnos
wsparcie jest przerwane w niektórych wersjach zsh
, gdy zbudowany z ostatnich wersji gcc
).
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-09-20 14:09:58
Aby odwrócić test, użyj "!". Jest to odpowiednik operatora logicznego "not" w innych językach. Spróbuj tego:
if [ ! -f /tmp/foo.txt ];
then
echo "File not found!"
fi
Lub napisane w nieco inny sposób:
if [ ! -f /tmp/foo.txt ]
then echo "File not found!"
fi
Lub możesz użyć:
if ! [ -f /tmp/foo.txt ]
then echo "File not found!"
fi
Or, presing all together:
if ! [ -f /tmp/foo.txt ]; then echo "File not found!"; fi
, które można zapisać (używając wtedy operatora" i":&&) jako:
[ ! -f /tmp/foo.txt ] && echo "File not found!"
Który wygląda krócej Tak:
[ -f /tmp/foo.txt ] || echo "File not found!"
Rzecz test
też może się liczyć. U mnie zadziałało (na podstawie powłoka Bash: sprawdź, czy plik istnieje lub nie):
test -e FILENAME && echo "File exists" || echo "File doesn't exist"
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-06-26 17:30:05
Ten kod również działa .
#!/bin/bash
FILE=$1
if [ -f $FILE ]; then
echo "File '$FILE' Exists"
else
echo "The File '$FILE' Does Not Exist"
fi
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-07-03 08:39:37
Najprostszy sposób
FILE=$1
[ ! -e "${FILE}" ] && echo "does not exist" || echo "exists"
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-08-01 01:35:00
Ten skrypt powłoki działa również do znalezienia pliku w katalogu:
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
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-08-05 21:01:40
Czasami przydatne może być użycie operatorów && i||.
Jak w (Jeśli masz komendę "test"):
test -b $FILE && echo File not there!
Lub
test -b $FILE || echo File there!
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-04-11 20:25:18