2012-06-13 12 views
14

Estoy tratando de crear un programa que elimine el contenido de la carpeta/tmp, estoy usando C/C++ en Linux.¿Cómo eliminar todos los archivos en una carpeta, pero no eliminar la carpeta usando las bibliotecas estándar de NIX?

system("exec rm -r /tmp") 

borra todo en la carpeta pero también elimina la carpeta que no quiero.

¿Hay alguna manera de hacer esto por algún tipo de script bash, llamado a través de system(); o hay una forma directa de hacerlo en C/C++?

Mi pregunta es similar a éste, pero no estoy en OS X ... how to delete all files in a folder, but not the folder itself?

+1

'rm -r/tmp/*' borrará el contenido de la carpeta. – AusCBloke

+1

Si desea invertir en el futuro, puede usar 'boost :: filesystem' para recorrer y eliminar cada uno. – chris

+3

@AusCBloke: Uhm ...que eliminará todos los archivos * visibles * de la carpeta (es decir, aquellos a los que se extiende '*'), pero no eliminará ningún archivo que comience por '.' –

Respuesta

14

En C/C++, se puede hacer:

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

En Bash, se puede hacer:

rm -r /tmp/* 

Esto eliminará todo dentro de/tmp, pero no/tmp en sí.

+0

¡Funciona maravillosamente, gracias! –

+7

Uhm ... eliminará todos los archivos visibles en la carpeta (es decir, aquellos a los que * se expande), pero no eliminará ningún archivo que comience. –

+0

Cualquier llamada a "sistema" desde C no es segura. https://www.securecoding.cert.org/confluence/pages/viewpage.action?pageId=2130132 – jackb

3

mediante el uso de usar el carácter comodín * puede eliminar todos los archivos con cualquier tipo de extensión.

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

+0

Uhm ... eso eliminará todos los archivos visibles en la carpeta (es decir, aquellos a los que * se expande), pero no eliminarán ningún archivo que comience. –

3

que puede hacer

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

Uhm ... eso eliminará todos los archivos visibles en la carpeta (es decir, aquellos a los que * se expande), pero no eliminará ningún archivo que comience. –

+0

@ DavidRodríguez-dribeas tienes razón. Edité mi respuesta en consecuencia. – ALiX

+0

Cualquier llamada al sistema no es segura https://www.securecoding.cert.org/confluence/pages/viewpage.action?pageId=2130132 – jackb

37
#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; 
} 

Usted no desea generar un nuevo shell a través de system() o algo por el estilo - que es un montón de gastos generales para hacer algo muy simple y hace suposiciones innecesarias (y dependencias) sobre lo que está disponible en el sistema.

+1

Uhm ... una respuesta que realmente funciona para archivos ocultos y no requiere un shell ! +1 (Aunque en el otro lado no eliminará directorios recursivamente, y no maneja errores ...) –

+6

La mejor respuesta :) –

+1

El código no compila –

1

En C/C++ se puede utilizar (incluyendo directorios ocultos):

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

Pero lo que si 'rm' o 'encontrar' servicios públicos no se dispongan para sh ?, mejor ir 'FTW' y 'eliminar ':

#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; 
} 
0

me di cuenta que es muy vieja pregunta, pero la construcción de una gran respuesta de Demitri he creado una función recursiva que va a eliminar archivos en subcarpetas si se desea

tampoco algunos manejo de errores, en el sentido de que pasa de nuevo a errno. El encabezado de la función está escrito para el análisis por doxygen. Esta función funciona en los casos de ejemplos simples que utilicé y elimina las carpetas ocultas y los archivos ocultos.

espero que esto ayude a alguien más en el futuro

#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; 
} 
0

Usted podría utilizar nftw(3). Primero, haga un pase para recopilar el conjunto de rutas de archivos para eliminar. Luego use unlink (para no-directorios) y rmdir(2) en una segunda pasada

Cuestiones relacionadas