如何在“system”命令中包含字符串变量(char *) - linux

时间:2010-11-27 11:24:06

标签: c linux grep

char * S =“你好”; //假设它是动态分配的

当S被视为值为“hello”的字符串时,我想在下面的语句中使用S.

system(“grep S searchtext.txt> result.txt”);

我该怎么做?

3 个答案:

答案 0 :(得分:8)

一般来说,像这样使用system是一个非常糟糕的主意。 system通过 shell 运行命令,这意味着传递给system的字符串受所有shell的变量扩展,命令扩展,特殊字符解释等的影响。

如果您坚持使用system必须首先清理您的字符串。最简单的方法是:

char *tmp = malloc(4*strlen(S)+3);
tmp[0] = '\'';
for (i=0,j=1; tmp[j]=S[i]; i++, j++)
    if (S[i]=='\'') tmp[++j]='\\', tmp[++j]='\'', tmp[++j]='\'';
tmp[j++] = '\'';
tmp[j++] = 0;
if (snprintf(cmd, sizeof cmd, "foo %s ...", tmp) >= sizeof cmd) goto error;
system(cmd);

此代码单引号整个字符串S,并用'\''替换任何嵌入的单引号。请注意,我还检查了命令行截断,以防它可能导致执行危险命令。

更好的选择是完全放弃system并执行您自己的forkexec来绕过shell。然后没有要解释的命令行;您可以完全控制传递给外部程序的参数(*argv[]数组)。

答案 1 :(得分:1)

在普通的C中,传统上使用snprintf()将命令行字符串格式化为缓冲区:

char buf[1024];
snprintf(buf, sizeof(buf), "grep '%s' searchtext.txt > result.txt", S);
system(buf);

当然,出于安全原因,如果S来自外部源(如文件,数据库或用户本人),则不应该这样做。这可能导致shell code injection

答案 2 :(得分:0)

有系统原语 - execl,execp。 因此,您可以在main中执行此操作execl("ls", "-la", NULL)