1

我有两个问题需要帮助解决。我有一个程序可以捕获密钥文件中的给定信息。就我而言,这些信息用于将不同的目录备份到给定位置 X 天。

该程序将压缩源目录,然后将它们推送到临时备份位置。然后它将在继续之前检查文件是否存在。

这是我的两个问题开始发挥作用的地方。

临时备份文件现在将被推送到一个文件夹,该文件夹在一段时间内循环并创建所需数量的文件夹。如果仅在桌面上,这效果很好。我的问题是我希望能够将这些文件放在我喜欢的任何地方。当我这样做时,它会出错并说“目录 1 已经存在”并停止。(这是持续时间的第一天)。

我还想将备份文件重命名为它们创建的当前日期。当我这样做时,它会将名称显示为“Success242483413.tgz”,而不是例如 082313。当我重命名临时目录中的文件时,它似乎可以工作,但问题是检查文件是否存在不知道如何读取日期和错误。

这是我的代码中的一个片段,我遇到这两个问题的 main() 。如果它有助于更​​好地理解它的运行,我可以发布所有代码。问题是粗体区域。

编辑:我不能加粗代码,所以它周围有注释的区域。

谢谢你,很抱歉这么长的帖子!

int main()
{
    //The key file, editable to your requirements.
    parseCodeFile cfg("key.cfg");
    std::string source = cfg.getValueOfKey<std::string>("source");
    std::string tempDestination = cfg.getValueOfKey<std::string>("tempDestination");
    std::string destination = cfg.getValueOfKey<std::string>("destination");
    int duration = cfg.getValueOfKey<int>("duration");
    int count, placeHolder, placeHolderAdvanced;
    count = 1;
    char command[256];
    snprintf(command, 256, "mkdir %s", tempDestination.c_str());
    system(command);
    // START RELEVANT
    snprintf(command, 256, "tar -cvzf %s/backup.tgz %s", tempDestination.c_str(), source.c_str());
    system(command);
    // END RELEVANT
    //Determines if the backup file exists. If not, closes the program.
    ifstream backupExists(tempDestination.c_str());
    if(backupExists.good())
    {
        std::cout << "\nCurrent backup.tgz file exists!\n\n";
    }
    else
    {
        std::cout << "\nFUUUUU NO FILE!\n";
        return 0;
    }
    //Removes the last folder in the group.
    snprintf(command, 256, "rm -rf %i", duration);
    system(command);
    while(count<duration)
    {
        //Holds the value that descends.
        placeHolder = duration - count;
        //Holds the value that ascends.
        placeHolderAdvanced = placeHolder + 1;
        snprintf(command, 256, "mv %i %i", placeHolder, placeHolderAdvanced);
        system(command);
        count++;
    }
    // START RELEVANT
    snprintf(command, 256, "mkdir %i", 1);
    system(command);
    snprintf(command, 256, "mv %s/backup.tgz %s/1", tempDestination.c_str(), destination.c_str());
    system(command);
    snprintf(command, 256, "mv %s/1/backup.tgz %s/1/`date +%m%d%y`.tgz", destination.c_str(), destination.c_str());
    system(command);
    // END RELEVANT
    return 0;
}
4

3 回答 3

2

如果你真的希望它是 C++ 代码,这里有一个经过测试的、有点理智的C++11 版本:

  • TODO使用execve或类似的代替system(需要一个dirExists()函数)
#include <fstream>
#include <sstream>
#include <iostream>
#include <string>
#include <cassert>
#include <cstring>

//////////////////////////////////////////////
// Utilities
std::string safe_quote(std::string const& v);
std::string getbackup_datename();
void run_command(std::string const& cmd);

//////////////////////////////////////////////
// Variadic command helper, does quoting
struct allow_err {};

void run_command(std::string const& cmd, allow_err) {
    run_command(cmd + " || true");
}

template <typename Arg, typename... Args>
   void run_command(std::string const& cmd, Arg arg1, Args&&... args) {
    std::ostringstream oss;
    oss << cmd << " " << safe_quote(arg1);
    run_command(oss.str(), std::forward<Args>(args)...);
}
// End Helpers / Utilities
//////////////////////////////////////////////

int main()
{
    //The key file, editable to your requirements.
    std::string source          = "/tmp/q";
    std::string tempDestination = "/tmp/q2_temp";
    std::string destination     = "/tmp/q2";
    int duration                = 6;

    std::string newname = tempDestination + "/" + getbackup_datename();
    {
        run_command("mkdir -p", tempDestination, destination);
        run_command("tar -czf", newname, source);
    }

    auto destdir = [=](int i) { return destination + "/" + std::to_string(i); };

    run_command("rm -rf", destdir(duration));

    for (int count=duration-1; count>0; --count)
        run_command("[ -d " + safe_quote(destdir(count)) + " ] && mv ", destdir(count), destdir(count+1), allow_err());

    run_command("mkdir -p", destdir(1));
    run_command("mv", newname, destdir(1) + '/');
}

//////////////////////////////////////////////
// Utilities implementations
std::string safe_quote(std::string const& v) 
{ 
    assert(v.find_first_of("'\"") == std::string::npos); // not implemented
    return "'" + v + "'"; 
}

void run_command(std::string const& cmd)
{
    std::string wrapped = "bash -c \"" + cmd + "\"";
    if (int exitcode = system(wrapped.c_str()))
    {
        std::cerr << "Command failed: " << wrapped << "\n";
        exit(exitcode);
    }
    //// For debug:
    //std::cout << "+" << cmd << "\n";
}

std::string getbackup_datename()
{
    char buf[20] = {0};
    auto t = time(NULL);
    strftime(buf, 20, "backup%m%d%y.tgz", localtime(&t));
    return buf;
}
于 2013-08-24T00:58:57.783 回答
1

这是一个健全的shell 脚本来完成这项工作:

#!/bin/bash
set -e
source key.cfg

mkdir -p "$tempDestination" "$destination"
newname="$tempDestination/$(date +"backup-%m%d%y.tgz")"
tar -czf "$newname" "$source"

# rotate backups
rm -rf "$destination/$duration" # Removes the last folder in the group.
for((count=$((duration-1)); $count > 0; count=$count-1))
do [ -d "$destination/$count" ] && 
        mv "$destination/$count" "$destination/$(($count + 1))"
done

mkdir -p "$destination/1" && mv "$newname" "$destination/1/"

笔记

  • rm -rf错误的文件夹(文件夹6存在下$destination,不在当前目录中!)
  • 您可能打算检查临时 backup.tgz。相反,您不小心只检查了该tempDestination文件夹...
  • 我使用set -e标志中止任何错误(所以如果tar失败,脚本将不会继续)
  • 我曾经date格式化存档名称。授权
  • 它会读取一个key.cfg文件,期待一个像这样的内容

    source="/tmp/q"
    tempDestination="/tmp/q2_temp"
    destination="/tmp/q2"
    duration=6
    
于 2013-08-23T23:28:00.717 回答
0

好的,所以我发现了文件夹的问题。当文件被移动到新文件夹时,mkdir 1 的计数仍在将它们发送到桌面。引发冲突。这是我所做的:

我添加// CHANGE了任何已更改的评论。

int main()
{
    //The key file, editable to your requirements.
    parseCodeFile cfg("key.cfg");
    std::string source = cfg.getValueOfKey<std::string>("source");
    std::string tempDestination = cfg.getValueOfKey<std::string>("tempDestination");
    std::string destination = cfg.getValueOfKey<std::string>("destination");
    int duration = cfg.getValueOfKey<int>("duration");
    int count, placeHolder, placeHolderAdvanced;
    count = 1;
    char command[256];
    // START CHANGE
    string Date = "backup-`date '+%m%d%y'`.tgz";                 // CHANGE
    snprintf(command, 256, "mkdir %s", tempDestination.c_str());
    system(command);
    snprintf(command, 256, "mkdir %s", destination.c_str());     // CHANGE
    system(command);                                             // CHANGE
    // END CHANGE
    snprintf(command, 256, "tar -cvzf %s/backup.tgz %s", tempDestination.c_str(), source.c_str());
    system(command);
    //Determines if the backup file exists. If not, closes the program.
    ifstream backupExists(tempDestination.c_str());
    if(backupExists.good())
    {
        std::cout << "\nCurrent backup.tgz file exists!\n\n";
    }
    else
    {
        std::cout << "\nFUUUUU NO FILE!\n";
        return 0;
    }
    //Removes the last folder in the group.
    snprintf(command, 256, "rm -rf %i", duration);
    system(command);
    while(count<duration)
    {
        //Holds the value that descends.
        placeHolder = duration - count;
        //Holds the value that ascends.
        placeHolderAdvanced = placeHolder + 1;
        // START CHANGE
        snprintf(command, 256, "mv %s/%i %s/%i", destination.c_str(),placeHolder, destination.c_str(),placeHolderAdvanced);
        system(command);
        // END CHANGE
        count++;
    }
    // START CHANGE
    snprintf(command, 256, "mkdir %s%s",destination.c_str(),"/1");
    system(command);
    snprintf(command, 256, "mv %s/backup.tgz %s/1/%s", tempDestination.c_str(), destination.c_str(),Date.c_str());
    system(command);
    // END CHANGE
    return 0;
}
于 2013-08-23T20:38:44.610 回答