我想编写一个生成gz文件的函数。该功能仅在Linux
上运行,因此我想使用gzip
命令(只需执行外部命令)。
到目前为止,我有这个:
bool generate_gz( const String& path )
{
bool res = false;
// LINUX
#ifndef __WXMSW__
if( !gzip_command_exists())
cout << "cannot compress file. 'gzip' command is not available.\n";
else
res = (0 == execute_command(String::Format("gzip %s", path.c_str())));
// WINDOWS
#else
// do nothing - result will be false
#endif
return res;
}
bool gzip_command_exists()
{
// TBD
}
的问题 的
有没有办法实施gzip_command_exists()
?如果是这样,它是否必须涉及运行(或尝试运行)gzip
命令?
答案 0 :(得分:4)
最简单的方法是通过system()
:"which gzip"
执行并查看系统调用的退出代码:
返回值 错误时返回的值为-1(例如fork(2)失败),否则返回命令的返回状态。后者返回状态 在... wait(2)中指定的格式。因此,命令的退出代码将是WEXITSTATUS(状态)。如果/ bin / sh不能 执行, 退出状态将是退出(127)的命令。
寻找什么:
:~$ which gzip
/bin/gzip
:~$ echo $?
0
:~$ which gzip11
:~$ echo $?
1
答案 1 :(得分:4)
如果您不想生成外部命令,可以使用stat函数检查文件是否存在以及它是否可在POSIX系统上执行。
你不想硬编码gzip的路径它稍微复杂一点。您将必须获取PATH环境变量,将其拆分为冒号,然后检查gzip的每个路径。路径变量的名称和格式也是POSIX特定的。检查getenv函数以读取路径,然后可以使用strtok将其拆分。
但是,值得检查是否值得怀疑,而不仅仅是尝试运行它并处理任何错误。
答案 2 :(得分:3)
您可以使用popen(3)来读取/usr/bin/which gzip
的输出(您还可以通过写入popen
- gzip > file.gz
命令使用它来动态压缩)。您还可以:FILE* pgzipv = popen("gzip --version", "r");
和fgets
第一行然后pclose
....
您可以考虑使用getenv("PATH")
,然后使用access
测试对每个构建的路径进行循环,方法是将/gzip
附加到PATH
中的每个元素}等等......您还可以fork
然后execvp
使用gzip
--version
stdout
和stderr
适当重定向等等。< / SUP>
请注意,当被要求执行不存在的程序时,popen(3)和system(3)都会失败(因为他们fork(2) /bin/sh一个-c
shell )。因此,您不需要测试gzip
的存在,并且您始终需要测试system
或popen
的成功(由于多种原因可能会失败,请参阅下面的{ {1}}失败,以及其他失败的文档。)
要挑剔,检查fork
是否存在是无用的:它[文件gzip
]可能(不太可能)在您的支票之间被移除 - 例如。如上所述/bin/gzip
或上面有access
,以及稍后调用popen
或system
;因此,首先检查popen
是否带来任何结果。
在大多数Linux系统上,gzip
通常可以gzip
使用(实际上/bin/gzip
始终安装);
这是file system hierarchy standard所要求的(如果安装了gzip
,它应该位于该文件路径上)。然后你可以使用access(2)例如代码如
gzip
最后,您根本不需要将#define GZIP_PATH "/bin/gzip" /* per FSH, see www.pathname.com/fhs */
if (access(GZIP_PATH, X_OK)) { perror(GZIP_PATH); exit(EXIT_FAILURE); };
进程分配到 gzip - 压缩文件。你可以(而且你应该)只是使用像zlib 这样的库(根据Linux Standard Base需要gzip
);你想要它的libz.so.1
,gzopen
,gzwrite
,gzprintf
,gzputs
等......功能!这样会更快(不需要fork(2)任何外部进程)并且更可靠(不依赖于某些外部程序,如gzclose
;即使gzip
不可能也会有效,因为限制已经已达成 - 请setrlimit(2) fork
RLIMIT_NPROC
内置bash(1)