Sprawdzanie, czy katalog istnieje w systemie Unix (wywołanie systemowe)

Nie jestem w stanie znaleźć rozwiązania mojego problemu w Internecie.

Chciałbym wywołać funkcję w Uniksie, przekazać ścieżkę katalogu i wiedzieć, czy istnieje. opendir() zwraca błąd, jeśli katalog nie istnieje, ale moim celem nie jest otwarcie, sprawdzenie błędu, zamknięcie go, jeśli nie ma błędu, ale raczej sprawdzenie, czy plik jest katalogiem, czy nie.

Czy jest na to jakiś wygodny sposób?
Author: Jonathan Leffler, 2010-09-30

8 answers

Istnieją dwie istotne funkcje w systemach POSIX: stat() i lstat () . Są one używane, aby dowiedzieć się, czy nazwa ścieżki odnosi się do rzeczywistego obiektu, do którego masz uprawnienia dostępu, a jeśli tak, zwracane dane mówią, jakiego typu jest obiekt. Różnica pomiędzy stat() i lstat() jest taka, że jeśli podana nazwa jest dowiązaniem symbolicznym, stat() podąża za dowiązaniem symbolicznym (lub dowiązaniami, jeśli są połączone ze sobą) i raportuje o obiekcie na końcu łańcucha dowiązań, podczas gdy lstat() informuje o samym dowiązaniu symbolicznym.

#include <sys/stat.h>

struct stat sb;

if (stat(pathname, &sb) == 0 && S_ISDIR(sb.st_mode))
{
    ...it is a directory...
}

Jeśli funkcja wskazuje, że się powiodła, używasz makra s_isdir () z <sys/stat.h> aby określić, czy plik jest rzeczywiście katalogiem.

Możesz również sprawdzić inne typy plików za pomocą innych makr S_IS*:

  • S_ISDIR - katalog
  • S_ISREG - plik zwykły
  • S_ISCHR - urządzenie znakowe
  • S_ISBLK - urządzenie blokowe
  • S_ISFIFO - FIFO
  • S_ISLNK - symboliczne link
  • S_ISSOCK - Gniazdo

(niektóre systemy dostarczają również kilka innych typów plików; {[14] } jest dostępny na przykład w Solarisie.)

 97
Author: Jonathan Leffler,
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-03-13 22:41:53

Możesz skorzystać z stat wywołanie systemowe poprzez podanie nazwy katalogu jako pierwszego argumentu. Jeśli katalog istnieje, zwracane jest 0, else -1, a errno zostanie ustawione na ENOENT

EDIT:

Jeśli zwracaną wartością jest 0, Konieczne jest dodatkowe sprawdzenie, czy argument jest katalogiem, a nie plikiem specjalnym file/symlink/char/BLK special file/FIFO file. Możesz skorzystać z pola st_modestat structure na to.

 5
Author: codaddict,
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
2010-09-30 07:11:04

You could use test -d

 3
Author: chigley,
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
2010-09-30 06:12:21

Jeśli mówisz o z muszli, jest dobra odpowiedź SO tutaj. podsumowując tę odpowiedź:

if [ -d "$DIRECTORY" ]; then
    # Control will enter here if $DIRECTORY exists
fi

Jeśli mówisz z poziomu programu C, możesz użyć stat():

{
    struct stat st;
    if(stat("/tmp",&st) == 0)
        printf(" /tmp is present\n");
}
 2
Author: Bryan,
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-05-23 12:09:54

Jeśli nie zależy ci na typie tego obiektu systemu plików, access (name, F_OK) sprawdza istnienie czegoś o tej nazwie. Jeśli chcesz mieć pewność, że jest to katalog, użyj stat () i sprawdź Typ za pomocą makra s_isdir ().

 1
Author: blaze,
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
2010-09-30 11:48:06

Testowany i działa dobrze:

int file_exist (char *filename)
{
    char s[200];
    sprintf(s, "test -e %s", filename);
    if (system(s) == 0){
        return 1;
    }else{
        return 0;
    }
}
 1
Author: Mehrdad Seyrafi,
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-07-24 09:04:26

Innym prostym sposobem byłoby:

int check(unsigned const char type) {
    if(type == DT_REG)
        return 1;
    if(type == DT_DIR)
        return 0;
    return -1;
}

Możesz przekazać struct dirent*obiektowy d_type do check funkcji.

Jeśli check zwróci 1, to ścieżka wskazuje na zwykły plik.

Jeśli check zwraca 0, to ścieżka wskazuje na katalog.

W Przeciwnym Razie nie jest to ani plik, ani katalog (może to być łącze blokowe / symboliczne itp..)

 1
Author: Aishwary Dewangan,
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-08-22 07:33:04

Myślę, że funkcja stat może robić to, co chcesz (nie testowałem jej pod kątem katalogów). W C++ Możesz również użyć biblioteki boost:: filesystem.

 0
Author: neodelphi,
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
2010-09-30 06:13:20