我正试图找出如何正确使用sh -c
或bash -c
。
我可以轻松地运行一个简单的命令,如"sh -c ls"
而无需参数。
当我试图添加参数时,问题出现了。
要做ls -ltga
,我必须这样做:
sh -c "ls -ltga"
这不是一个大问题,除了我试图编写自己的小shell程序,
当我使用execve
时,我尝试:
Argument #: string
0: sh
1: -c
2: "ls
3: -ltga"
它给了我一个错误,说它在找到下一个'"'
之前达到了EOF
我也试过了:
0: sh
1: -c
2: "ls -ltga"
它返回给我说它找不到名为"ls -ltga"
有人知道我做错了吗?
答案 0 :(得分:3)
你不应该在execve()
的参数中加注引号。它应该像这样调用:
char *args = { "sh", "-c", "ls -ltga", 0};
execve("/bin/sh", args);
execve()
的第一个参数必须是可执行文件的路径(通常是完整路径)。
答案 1 :(得分:0)
shell期望的符号是sh -c "command plus arguments"
。所以,你作为“解决方法”所做的事实上是shell要求的。
另一种方法是使用execvp()
来运行ls
:
char *args[] = { "ls", "-lgta", 0 };
execvp(args[0], args);
fprintf(stderr, "Oops: failed to find 'ls'\n");
exit(1);
我还需要能够运行带有正则表达式的命令,例如
"rm *.c"
,但是无法在execve()
内运行(大多数情况下),所以我试图通过将整个命令集传递给“sh -c”。有什么想法吗?
如果你想要元字符扩展,你必须调用shell来执行它(或者编写相同的代码来执行它 - 这是可能的,并且对于标准POSIX函数来说并不太困难)。
要运行“rm *.c
”,请使用:
char *args[] = { "/bin/sh", "-c", "rm *.c", 0 };
execv(args[0], args);
或者,如果你有一个环境,你需要专门传递(我认为它由envp
指出):
char *args[] = { "/bin/sh", "-c", "rm *.c", 0 };
execve(args[0], args, envp);
exec*
函数调用后不要忘记错误处理;它可能会失败。