如何为来自C程序的Unix system()调用构造一个字符串

时间:2014-10-21 19:23:41

标签: c unix command

我正在尝试让我的C程序使用system()在Unix中运行命令。

我可以制作类似system("stat myFile")的内容,其中myFile是我程序中的变量吗? 还有其他方法吗?

3 个答案:

答案 0 :(得分:1)

system()采用指向char或char数组的指针。您可以按如下方式构建它:

#include <stdio.h>
#include <stdlib.h>

char command[256]; /* Big enough for "stat " + longest file name. */
char *myFile = "/my/file";
/* ... */
sprintf (command, "stat %s", myFile);
system(commmand);

这应该让你前进,但请注意,如果myFile是一个looooong名称,由于可能的缓冲区溢出,像256这样的硬限制不是防弹编码。 Supercalifragilisticexpialidocious文件名不是闻所未闻的:-)如果你想像专业人士那样做,下一步就是阅读snprintf手册并询问你的shell getconf _POSIX_PATH_MAX

答案 1 :(得分:1)

答案简短:system有很多你不想处理的问题:

  1. 它通过shell运行外部程序,因此您必须担心在构建字符串时正确转义任何文件名或其他选项。如果不这样做可能会产生危险的错误。

  2. system暂停您的程序,直到您运行的程序完成。

  3. 无法通过system回读您运行的程序的输出。

  4. 使用popen解决除shell转义之外的所有问题,非常方便。使用forkexecvpposix_spawnp会更复杂,但可以解决上述所有问题以及更多问题。

答案 2 :(得分:0)

对于运行stat(1)命令的特定情况,您可以改为使用stat(2)系统调用。见syscalls(2)。因此使用

  struct stat mys;
  memset (&mys, 0, sizeof(mys));
  if (stat(filename, &mys)) { perror(filename); exit(EXIT_FAILURE); };
  /// use mys

通常,您可以考虑使用snprintf(3)asprintf(3)来构建命令字符串,并使用popen(3)system(3)来运行它。如果你可以避免这种情况,这是不可取的(code injection的可能性,所以你需要考虑shell转义等等。)。

您还应该阅读Advanced Linux Programming,或许要了解fork(2)execve(2)pipe(2)等等。