Ответ 1
В C/С++ вы можете сделать:
system("exec rm -r /tmp/*")
В Bash вы можете сделать:
rm -r /tmp/*
Это приведет к удалению всего внутри /tmp, но не/tmp.
Я пытаюсь создать программу, которая удаляет содержимое папки /tmp, я использую C/С++ в linux.
system("exec rm -r /tmp")
удаляет все в папке, но также удаляет папку, которая мне не нужна.
Есть ли способ сделать это с помощью bash script, вызванного через system()
; или есть прямой способ, я могу сделать это в C/С++?
Мой вопрос похож на этот, но не на OS X... как удалить все файлы в папке, но не в самой папке?
В C/С++ вы можете сделать:
system("exec rm -r /tmp/*")
В Bash вы можете сделать:
rm -r /tmp/*
Это приведет к удалению всего внутри /tmp, но не/tmp.
#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;
}
Вы не хотите создавать новую оболочку с помощью system()
или что-то в этом роде - что много накладных расходов делает что-то очень простое и делает ненужными предположения (и зависимости) о том, что доступно в системе.
используя символ подстановки *
, вы можете удалить все файлы с любым типом расширения.
system("exec rm -r /tmp/*")
вы можете сделать
system("exec find /tmp -mindepth 1 -exec rm {} ';'");
В C/С++ вы можете использовать (включая скрытые каталоги):
system("rm -r /tmp/* /tmp/.*");
system("find /tmp -mindepth 1 -delete");
Но что, если утилиты 'rm' или 'find' недоступны для sh?, лучше пойти 'ftw' и '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;
}
Я понимаю, что это очень старый вопрос, но, основываясь на отличном ответе Демитри, я создал функцию, которая будет рекурсивно удалять файлы в подпапках при желании
Он также выполняет обработку some, поскольку он передает обратно errno. Заголовок функции написан для синтаксического анализа doxygen. Эта функция работает в простых примерах, которые я использовал, и удаляет скрытые папки и скрытые файлы.
Я надеюсь, что это поможет кому-то еще в будущем
#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;
}
Вы можете использовать nftw (3). Сначала сделайте проход, чтобы собрать набор путей к файлу для удаления. Затем используйте unlink
(для не-каталогов) и rmdir (2) за второй проход