Wie lösche ich alle Dateien in einem Ordner, aber lösche den Ordner nicht mit NIX-Standardbibliotheken?

Lesezeit: 6 Minuten

Benutzer-Avatar
Das Finden von Nemo 2 geschieht.

Ich versuche, ein Programm zu erstellen, das den Inhalt des /tmp-Ordners löscht, ich verwende C/C++ unter Linux.

system("exec rm -r /tmp")

löscht alles im Ordner, aber es löscht auch den Ordner, den ich nicht möchte.

Gibt es eine Möglichkeit, dies durch eine Art Bash-Skript namens via system(); oder gibt es eine direkte Möglichkeit, dies in C/C++ zu tun?

Meine Frage ähnelt dieser, aber ich bin nicht auf OS X … wie lösche ich alle Dateien in einem Ordner, aber nicht den Ordner selbst?

  • rm -r /tmp/* löscht den Inhalt des Ordners.

    – AusCBloke

    13. Juni 2012 um 2:36 Uhr

  • Wenn Sie in die Zukunft investieren möchten, könnten Sie verwenden boost::filesystem zu durchlaufen und jedes zu löschen.

    – Chris

    13. Juni 2012 um 2:36 Uhr

  • @AusCBloke: Ähm … das wird alles löschen sichtbar Dateien im Ordner (d. h. diejenigen, die * erweitert auf), löscht aber keine Datei, die mit beginnt .

    – David Rodríguez – Dribeas

    13. Juni 2012 um 2:37 Uhr

  • @DavidRodríguez-dribeas: Oh ja, guter Punkt.

    – AusCBloke

    13. Juni 2012 um 2:39 Uhr

  • @DavidRodríguez-dribeas: Nebenbei bemerkt, könnte das Löschen des Inhalts von /tmp irgendetwas schaden?

    – Die Suche nach Nemo 2 findet statt.

    13. Juni 2012 um 2:51 Uhr

Benutzer-Avatar
Demitri

#include <stdio.h>
#include <dirent.h>

int main()
{
    // These are data types defined in the "dirent" header
    DIR *theFolder = opendir("path/of/folder");
    struct dirent *next_file;
    char filepath[256];

    while ( (next_file = readdir(theFolder)) != NULL )
    {
        // build the path for each file in the folder
        sprintf(filepath, "%s/%s", "path/of/folder", next_file->d_name);
        remove(filepath);
    }
    closedir(theFolder);
    return 0;
}

Sie möchten keine neue Shell über spawnen system() oder so ähnlich – das ist eine Menge Overhead, um etwas sehr Einfaches zu tun, und es macht unnötige Annahmen (und Abhängigkeiten) darüber, was auf dem System verfügbar ist.

  • Ähm … eine Antwort, die tatsächlich für versteckte Dateien funktioniert und keine Shell erfordert! +1 (Obwohl es auf der anderen Seite Verzeichnisse nicht rekursiv löscht und keine Fehler behandelt …)

    – David Rodríguez – Dribeas

    13. Juni 2012 um 2:55 Uhr


  • Sie möchten wahrscheinlich festlegen if (0==strcmp(next_file->d_name, ".") || 0==strcmp(next_file->d_name, "..")) { continue; } am Anfang der while-Anweisung, wenn Sie die Dateien nicht löschen möchten “.” und “..”

    – Daniel

    22. Februar 2014 um 17:17 Uhr

In C/C++ könnten Sie Folgendes tun:

system("exec rm -r /tmp/*")

In Bash könnten Sie Folgendes tun:

rm -r /tmp/*

Dadurch wird alles in /tmp gelöscht, aber nicht /tmp selbst.

  • Ähm … das löscht alle sichtbaren Dateien im Ordner (dh diejenigen, die mit * erweitert werden), aber es werden keine Dateien gelöscht, die mit beginnen.

    – David Rodríguez – Dribeas

    13. Juni 2012 um 2:44 Uhr

  • Jeder Aufruf von “System” von C ist nicht sicher. securecoding.cert.org/confluence/pages/…

    – jackb

    25. August 2016 um 11:13 Uhr

  • @jackb: Ich stimme zu. Denken Sie jedoch (da Sie abgelehnt haben) daran, dass das OP tat Fragen Sie: “…Gibt es eine Möglichkeit, dies durch eine Art Bash-Skript zu tun, das über das System aufgerufen wird …”

    – Jay Sullivan

    29. August 2016 um 14:12 Uhr

  • @jackb: Dem stimme ich zu system ist schlecht, aber meine Antwort erweiterte nur die Frage des OP, die eindeutig im Zusammenhang mit der Verwendung stand system. Sie sollten Ihren Punkt als Feedback zur ursprünglichen Frage posten.

    – Jay Sullivan

    29. August 2016 um 14:22 Uhr


  • Keine Entschuldigung, andere Benutzer haben eine korrektere Antwort gegeben. Ich habe eine dieser Antworten positiv bewertet. Ich bin mir ziemlich sicher, dass Sie das nächste Mal vorsichtiger sein werden.

    – jackb

    29. August 2016 um 14:24 Uhr


Benutzer-Avatar
ALiX

du kannst tun

system("exec find /tmp -mindepth 1 -exec rm {} ';'");

  • Ähm … das löscht alle sichtbaren Dateien im Ordner (dh diejenigen, die mit * erweitert werden), aber es werden keine Dateien gelöscht, die mit beginnen.

    – David Rodríguez – Dribeas

    13. Juni 2012 um 2:54 Uhr

  • @DavidRodríguez-dribeas du hast recht. Ich habe meine Antwort entsprechend bearbeitet.

    – ALIX

    13. Juni 2012 um 3:20 Uhr

  • Jeder Aufruf von System ist nicht sicher securecoding.cert.org/confluence/pages/…

    – jackb

    25. August 2016 um 11:14 Uhr

Benutzer-Avatar
eqzx

indem Sie den Platzhalter verwenden * Zeichen können Sie alle Dateien mit jeder Art von Erweiterung löschen.

system("exec rm -r /tmp/*")

In C/C++ können Sie verwenden (einschließlich versteckter Verzeichnisse):

system("rm -r /tmp/* /tmp/.*");
system("find /tmp -mindepth 1 -delete");

Aber was ist, wenn die Dienstprogramme ‘rm’ oder ‘find’ nicht verfügbar sind, gehen Sie besser zu ‘ftw’ und ‘remove’:

#define _XOPEN_SOURCE 500
#include <ftw.h>

static int remove_cb(const char *fpath, const struct stat *sb, int typeFlag, struct FTW *ftwbuf)
{
    if (ftwbuf->level)
        remove(fpath);
    return 0;
}

int main(void)
{
    nftw("./dir", remove_cb,  10, FTW_DEPTH);
    return 0;
}

Mir ist klar, dass dies eine sehr alte Frage ist, aber aufbauend auf Demitris großartiger Antwort habe ich eine Funktion erstellt, die Dateien in Unterordnern auf Wunsch rekursiv löscht

Das tut es auch etwas Fehlerbehandlung, indem es errno zurückgibt. Der Funktionsheader ist für das Parsen durch doxygen geschrieben. Diese Funktion funktioniert in den einfachen Beispielfällen, die ich verwendet habe, und löscht versteckte Ordner und versteckte Dateien.

Ich hoffe, dies hilft jemand anderem in der Zukunft

#include <stdio.h>
#include <dirent.h>
#include <sys/stat.h>
#define SUCCESS_STAT 0

/**
 * checks if a specific directory exists
 * @param dir_path the path to check
 * @return if the path exists
 */
bool dirExists(std::string dir_path)
{
    struct stat sb;

    if (stat(dir_path.c_str(), &sb) == 0 && S_ISDIR(sb.st_mode))
        return true;
    else
        return false;
}

/**
 * deletes all the files in a folder (but not the folder itself). optionally
 * this can traverse subfolders and delete all contents when recursive is true
 * @param dirpath the directory to delete the contents of (can be full or
 * relative path)
 * @param recursive true = delete all files/folders in all subfolders
 *                  false = delete only files in toplevel dir
 * @return SUCCESS_STAT on success
 *         errno on failure, values can be from unlink or rmdir
 * @note this does NOT delete the named directory, only its contents
 */
int DeleteFilesInDirectory(std::string dirpath, bool recursive)
{
    if (dirpath.empty())
        return SUCCESS_STAT;

    DIR *theFolder = opendir(dirpath.c_str());
    struct dirent *next_file;
    char filepath[1024];
    int ret_val;

    if (theFolder == NULL)
        return errno;

    while ( (next_file = readdir(theFolder)) != NULL )
    {
        // build the path for each file in the folder
        sprintf(filepath, "%s/%s", dirpath.c_str(), next_file->d_name);

        //we don't want to process the pointer to "this" or "parent" directory
        if ((strcmp(next_file->d_name,"..") == 0) ||
            (strcmp(next_file->d_name,"." ) == 0) )
        {
            continue;
        }

        //dirExists will check if the "filepath" is a directory
        if (dirExists(filepath))
        {
            if (!recursive)
                //if we aren't recursively deleting in subfolders, skip this dir
                 continue;

            ret_val = DeleteFilesInDirectory(filepath, recursive);

            if (ret_val != SUCCESS_STAT)
            {
                closedir(theFolder);
                return ret_val;
            }
        }

        ret_val = remove(filepath);
        //ENOENT occurs when i folder is empty, or is a dangling link, in
        //which case we will say it was a success because the file is gone
        if (ret_val != SUCCESS_STAT && ret_val != ENOENT)
        {
            closedir(theFolder);
            return ret_val;
        }

    }

    closedir(theFolder);

    return SUCCESS_STAT;
}

Benutzer-Avatar
Basile Starynkevitch

Du könntest benutzen nftw(3). Führen Sie zunächst einen Durchgang durch, um die zu entfernenden Dateipfade zu sammeln. Dann benutze unlink (für Nicht-Verzeichnisse) und rmdir(2) in einem zweiten Durchgang

1354170cookie-checkWie lösche ich alle Dateien in einem Ordner, aber lösche den Ordner nicht mit NIX-Standardbibliotheken?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy