如何在“system”命令中包含stringvariables(char *) – linux

char * S =“hello”; //假定它是正确dynamic分配的

当S被视为值为“hello”的string时,我想在下面的语句中使用S。

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

我该怎么做呢?

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

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

当然,出于安全原因,如果S来自外部来源,如文件,数据库或用户自己,则不应该这样做。 这可能会导致shell代码注入 。

一般来说,使用这样的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[]数组)。

那么有系统原语 – execl,execp。 所以你可以在main中做execl("ls", "-la", NULL)