从 c++ 程序创建 tar.gz-archive 不起作用
Posted
技术标签:
【中文标题】从 c++ 程序创建 tar.gz-archive 不起作用【英文标题】:Creating tar.gz-archive from c++ program does not work 【发布时间】:2016-09-15 06:13:18 【问题描述】:我使用以下代码 sn-p 在广泛的测量软件中创建tar.gz
-archive。在几个文件中收集了一些数据后,我想存档并压缩它们以备后用。
当我从 shell 启动程序时,一切正常,所有数据都被正确收集和存档。
但是程序应该在嵌入式 Linux 系统启动后自动启动。当它通过/etc/init.d
中的脚本启动时,没有数据文件被存档/压缩,即使我得到了返回值0
。此外,创建了 tar.gz 文件,但它是空的。
其他一切正常。
谁能解释一下,在这种自动启动的特殊情况下我必须做什么?
int returnValue = -1;
std::string jobString = RESULT_PATH;
jobString += "/";
jobString += lastJobString;
std::string jobFiles = lastJobString + "*.*";
std::string cmd = "tar cvf - ";
cmd += jobFiles;
cmd += " | gzip > ";
cmd += jobString;
cmd += ".tar.gz";
std::cout << "archiving and compressing " << jobFiles << ": " << cmd << std::flush << std::endl;
returnValue = system(cmd.c_str());
std::cout << "archiving and compressing finished. Code: " << returnValue << std::flush << std::endl;
我知道有几个库,如libarchive
、libtar
等。使用它们不像触发系统命令那么懒惰,但我想知道为什么这对我的情况不起作用。
另外,我的忙箱中tar
的版本不支持选项z
。
【问题讨论】:
有时从脚本启动程序时,并没有设置所有路径,因此您必须使用完整路径,例如/bin/tar
。您的.tar.gz
文件将始终在您使用>
运算符时创建,该运算符会在出错时创建一个空文件。您还可以将 stderr 重定向到日志文件以查看错误消息。您也可以简单地使用 tar czf archive.tar.gz filenames
而无需手动调用 gzip 并将 stdout 重定向到文件。
@Karsten Koop 感谢您的回答。正如我所提到的,作为调用的返回值,我没有收到任何错误。此外,我忙碌的盒子中tar
的版本没有z
的选项。
Return 0 并不意味着命令实际运行。甚至 system("blabla 123 | gzip > out") 也会像我刚刚尝试的那样返回 0。
【参考方案1】:
我终于找到了解决我的问题的方法,也许对于守护进程调用系统命令的所有情况:
诀窍是通过命令sh
创建一个新的shell,并在调用tar 函数之前更改当前目录:
std::string cmd = "sh -c \" cd ";
cmd += SOURCE_DIR;
cmd+= " && tar cvf - ";
cmd += jobFiles;
cmd += " | gzip > ";
cmd += jobString;
cmd += ".tar.gz";
returnValue = system(cmd.c_str());
也许这会帮助其他用户解决同样的问题。
【讨论】:
大多数tar
程序(当然还有GNU tar...)接受-C
程序选项来更改目录。你可以在你的 C++ 程序中调用chdir(2)。
您的系统命令脆弱且不安全:如果某些恶意用户将sourceDir
设置为rm -rf $HOME
怎么办?当心code injection !!
SOURCE_DIR
是在头文件中定义的常量字符串。以上是关于从 c++ 程序创建 tar.gz-archive 不起作用的主要内容,如果未能解决你的问题,请参考以下文章
为啥可以从 QWidget 创建一个对象而不在 C++ 程序的开头包含它
如何从 C++ 为 Xamarin.Android 创建 C# DLL