1

解決する上で助けてほしい問題が 2 つあります。指定された情報をキーファイルにキャプチャするプログラムがあります。私の場合、情報は、さまざまなディレクトリを特定の場所に X 日間バックアップするためのものです。

プログラムはソース ディレクトリを圧縮し、一時的なバックアップ場所にプッシュします。次に、先に進む前にファイルが存在するかどうかを確認します。

ここで、私の 2 つの問題が発生し始めます。

一時バックアップ ファイルがフォルダーにプッシュされ、一定期間、必要な量のフォルダーがループして作成されます。これは、デスクトップ上でのみうまく機能します。私の問題は、これらのファイルを好きな場所に配置できるようにしたいということです。これを行うと、エラーが発生し、「ディレクトリ 1 は既に存在します」と表示されて停止します。(これは期間の最初の日です)。

また、バックアップ ファイルの名前を、作成された現在の日付に変更したいと考えています。これを行うと、たとえば082313ではなく「Success242483413.tgz」という名前が表示されます。一時ディレクトリのファイルの名前を変更すると、動作しているように見えますが、問題はファイルが存在するかどうかを確認するチェックです。日付の読み方とエラー。

これが私のコードのスニペットです。 main() で、これら 2 つの問題が発生しています。よりよく理解するために実行を確認するのに役立つ場合は、すべてのコードを投稿できます。問題は太字の部分です。

編集:コードを太字にすることはできないので、その周りにコメントがある領域です。

ありがとうございます!

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 バージョンを次に示します。

  • TODOexecveの代わりにまたは類似のものを使用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

これを実行するための適切なシェル スクリプトを次に示します。

#!/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 に答える