snprintf“date”和文件位置问题

时间:2013-08-23 15:14:24

标签: c++ linux printf

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

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

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

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

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

这是我的代码片段,主要()我遇到这两个问题。 我可以发布所有代码,如果它有助于看到它运行以更好地理解。问题是大胆的问题。

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

谢谢你,很抱歉这篇长篇文章!

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

3 个答案:

答案 0 :(得分: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;
}

答案 1 :(得分: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下,而不是当前目录中!)
  • 您可能打算检查 temp backup.tgz 。相反,您不小心检查了tempDestination文件夹...
  • 我使用set -e标志中止任何错误(因此如果tar失败,则脚本将无法继续)
  • 我使用date格式化存档名称。 man date
  • 它会读取key.cfg文件,期待像

    这样的内容
    source="/tmp/q"
    tempDestination="/tmp/q2_temp"
    destination="/tmp/q2"
    duration=6
    

答案 2 :(得分: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;
}