我有两个问题需要帮助解决。我有一个程序,可以在密钥文件中捕获给定的信息。就我而言,该信息用于将不同目录备份到给定位置,持续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;
}
答案 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
下,而不是当前目录中!)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;
}