简体   繁体   English

如何从C程序为Unix system()调用构造字符串

[英]How to construct a string for a Unix system() call from C program

I'm trying to make my C program run a command in Unix using system() . 我试图让我的C程序使用system()在Unix中运行命令。

Can I make something like system("stat myFile") , where myFile is a variable in my program? 我可以制作类似system("stat myFile") ,其中myFile是程序中的变量吗? Is there any other way possible? 还有其他办法吗?

system() takes a pointer-to-char or a char array. system()采用指向char的指针或char数组。 You can construct it as follows: 您可以按以下方式构造它:

#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);

This should get you going, but note that a hard limit like 256 is not bullet-proof coding due to a possible buffer overrun if myFile is a looooong name. 这应该可以帮助您,但是请注意,如果myFile是一个looooong名称,则硬限制(例如256)不是防弹编码,因为可能会导致缓冲区溢出。 Supercalifragilisticexpialidocious file names are not unheard of :-) If you want to do it like a pro, the next step would be to read the snprintf manual and ask your shell for getconf _POSIX_PATH_MAX . Supercalifragilisticexpialidocious文件名不是闻所未闻的:-)如果您想像专业人士一样去做,下一步就是阅读snprintf手册,并向您的shell询问getconf _POSIX_PATH_MAX

The short answer: don't . 简短的答案: 不要 system has lots of problems you don't want to deal with: system有很多您不想处理的问题:

  1. It runs the external program via the shell, so you have to worry about properly escaping any filenames or other options you pass when building your string. 它通过外壳程序运行外部程序,因此您必须担心在构建字符串时是否正确转义了传递的任何文件名或其他选项。 Failure to do so could create dangerous bugs. 否则可能会造成危险的错误。

  2. system suspends your program until the program you run finishes. system暂停您的程序,直到您运行的程序完成。

  3. There's no way to read back the output from the program you run via system . 无法从通过system运行的程序中读取输出。

Using popen solves all of the problems except shell escaping and is very convenient. 使用popen解决了除外壳转义之外的所有问题,非常方便。 Using fork and execvp , or posix_spawnp , is more complex but solves all of the above problems and more. 使用forkexecvpposix_spawnp更为复杂,但可以解决上述所有问题,甚至更多。

For that particular case of running stat(1) command, you could use instead the stat(2) syscall instead. 对于运行stat(1)命令的特定情况,可以改为使用stat(2) syscall。 See syscalls(2) . 参见syscalls(2) Hence use 因此使用

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

In general you might consider using snprintf(3) or asprintf(3) to build a command string, and using popen(3) or system(3) to run it. 通常,您可能会考虑使用snprintf(3)asprintf(3)来构建命令字符串,并使用popen(3)system(3)来运行它。 This is not advisable if you can avoid that (possibility of code injection , so you need to consider shell escapes, etc...). 如果您可以避免这种情况,则不建议这样做(可以进行代码注入 ,因此需要考虑shell换码等)。

You should also read Advanced Linux Programming , perhaps to know about fork(2) , execve(2) , pipe(2) etc... 您还应该阅读Advanced Linux Programming ,也许要了解fork(2)execve(2)pipe(2)等...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM