我正在编写一个C程序,该程序使用execlp()
来运行linux命令行工具convert
。此命令采用可选参数。然而,当它与execlp()
一起使用时,我的C程序无法识别我传入的标志,因此无法正确执行该命令。
例如,如果我在终端convert -resize 10% src.jpg dst.jpg
中运行此命令,它将调整src图像的大小10%,并将其保存到dst。然而,当我用这个代码运行我的C程序时
rc = execlp("convert", "-resize 10%", src, dst, NULL);
我的计算机无法识别resize -10%
标志,也不会对我的源映像执行任何操作。为什么?
按照惯例,进程的第一个参数(可访问为argv[0]
(是进程的名称。您还没有包括这一点,所以"-resize 10%"
被读取为进程名称,而不是选项。
此外,"-resize 10%"
实际上是由一个空格分隔的两个参数,因此需要将它们拆分。
rc = execlp("convert", "convert", "-resize", "10%", src, dst, NULL);
很可能,-resize
应该是一个选项,10%
应该是另一个选项:
rc = execlp("convert", "convert", "-resize", "10%", src, dst, NULL);
如果您有可变数量的参数,那么使用execlp()
是个坏主意——请改用execvp()
,构建一个以null指针终止的参数数组。仅当参数列表固定时才使用execlp()
。
char *args[6];
int i = 0;
args[i++] = "convert";
args[i++] = "-resize";
args[i++] = "10%";
args[i++] = src;
args[i++] = dst;
args[i++] = NULL;
rc = execvp(args[0], args);
请注意,这个公式确保程序名称被正确传递——一次作为在$PATH
上搜索的字符串,一次作为执行程序的argv[0]
。
对于execlp()
,正如dbush所指出的,您必须重复命令名——一次指定可执行文件,一次指定argv[0]
的值。
请注意,没有什么可以阻止您通过argv[0]
告诉程序,它的名称与您执行的名称完全不同。这种情况很少发生(shell不会这样做(,但当您自己编写代码时,这是可能的。