main(int argc,char **argv)
{
int i;
for(i=1;i<argc;i++)
{
execlp(argv[i],"",NULL);
}
}
我想从命令行输入同时执行多个命令。
所以,在命令行中我给了./a.out date & cal & pwd & ls
在输出中,我可以同时执行所有命令。
但是当我第一次调用execlp时,它应该采用第一个参数,即argv [1],并且应该按进程日期替换整个进程,并且应该在执行后终止整个进程。但如果它终止,那怎么能再次继续for循环?
答案 0 :(得分:1)
for
循环不会继续。只运行第一个命令,并在运行execlp
时替换该进程(假设成功)。
但是如果你打印argc
的值,你会发现它等于2,即即使没有execlp
调用,for循环也只会运行一次迭代。这是因为在shell中,当您运行a & b & c &
时,它将分别在后台运行每个命令a
,b
,c
。在这种情况下,它使用命令行./a.out date
调用您的流程。其他命令由shell直接运行,而不是由您的进程运行。
答案 1 :(得分:1)
运行cal
,pwd
和ls
的程序不是您的程序,它是您正在使用的shell。它使用唯一的参数date
调用您的程序,并在后台运行它。然后在后台启动cal
,pwd
和ls
。
如果您希望程序将它们作为参数接收,请删除&
或将它们放在引号中。然后你会看到你的程序确实没有运行循环(除非execl
失败)。
答案 2 :(得分:1)
阅读execlp(3)的文档(更常见的是您正在使用的每个函数)。另请阅读Advanced Linux Programming。
如果您想将date
,cal
,pwd
,ls
传递到您的计划a.out
,则需要运行命令a.out date cal pwd ls
(没有任何&
由shell解释。 shell是您程序的globbing参数。请参阅glob(7)。
顺便说一句,请不要将您的计划命名为a.out
。使用像
gcc -Wall -Wextra -g yourprog.c -o yourprog
编译代码然后运行./yourprog
(可能在gdb
调试器内)。
execlp
函数调用在成功时未返回的execve(2)系统调用。因此execlp
和execve
只会在失败时返回。
因此,当您第一次执行循环时,程序会停止,因为date
已成功执行(这意味着date
已将替换为 ./yourprog
process)。
也许你想要执行一系列程序,直到找到一个程序(例如./yourprog silly date
,而你的系统中不存在silly
。然后你应该编写像
for(i=1;i<argc;i++) {
execlp(argv[i],"",NULL);
// this is reached only if the above `execlp` failed, so
perror(argv[i]);
}
更有可能的是,您希望依次执行每个程序(例如./yourprog date id ls
)。然后,您需要在循环中调用fork(2) 。您将保留fork
的结果,并且应该针对fork
的失败进行测试。在子流程中,您可以拨打execve(2)或execlp(3)。在父进程中,您需要致电waitpid(2)以避免zombie processes。
另一种可能性是您想要一次运行所有程序。你需要两个循环,一个执行fork
- s(并将子pids保留在某个数组中),另一个执行wait(2)。
如果你想要,例如阅读您在子进程中运行的程序的输出(或编写标准输入),您需要了解pipe(7) - s并在 {之前调用pipe(2) {1}}。如果要并行运行它们并从多个管道读取,则需要使用多路复用系统调用,如poll(2)