目前正致力于收集linux shell的输入命令并执行它们创建子进程的程序。
#include <sys/types.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
int main(int argc, char * argv[])
{
int pid, status;
if (argc < 2) {
printf("Usage: %s command, [arg1 [arg2]...]\n", argv[0]);
return EXIT_FAILURE;
}
printf("Starting %s...\n", argv[1]);
pid = fork();
if (pid == 0) {
execvp(argv[1], &argv[1]);
perror("execvp");
return EXIT_FAILURE; // Never get there normally
} else {
if (wait(&status) == -1) {
perror("wait");
return EXIT_FAILURE;
}
}
return EXIT_SUCCESS;
}
使用像./program command arg
这样的输入,但需要使用args接收各种命令,例如:./program command arg command arg .....
有什么建议吗?
答案 0 :(得分:0)
你实际上没有说出你的问题是什么,但我的猜测是你在解决每个分叉进程如何使用参数时遇到问题。
我猜你所做的就是每次分叉时你需要将argv
指针前进到下一个命令/ arg对。当命令为零终止符时,此分叉循环终止。
我希望我理解你的问题,因为你还没有说明你遇到的这个问题的哪个方面。
答案 1 :(得分:0)
argc
告诉您argv
您需要使用该信息从argv
中提取它们。
请注意,这并不能解决具有不同args数量的命令的问题。
因此回复评论进行编辑:
您可以查看允许您执行此操作的getopt()
:
./program -c "command arg1 arg2" -c "command arg1" ...
问题是您需要能够区分命令/ arg集。 getopt()
至少会让你到中途,然后你只需要解析每一组。虽然这真是太过分了,因为这是你唯一的输入类型。在这种情况下,迭代argv
同样容易。
另一种选择是用分隔符分隔它们:
./program command arg1, command arg1 arg2, ...
您需要遍历argv
并查找逗号以了解命令/ arg集已完成。或者将所有argv连接成一个字符串并使用strtok()
。有点丑陋的恕我直言,但可行。
答案 2 :(得分:0)
shell是一个复杂的软件,我最近不得不为操作系统类实现一个,这很困难;我们只需要为每个输入控制一个命令(虽然我们也必须实现I / O重定向和管道,并且必须手动进行路径搜索然后使用execv()
执行)。
您将遇到的问题在于,确实没有办法判断命令行参数数组中的下一个arg字符串是否是前一个命令的命令或参数。你可以区分命令及其args的唯一方法是知道它将交替command arg command arg ...
,或者每个命令有一些其他标准化的参数(这不是很有用)或者在分号之间有一个分隔符:command arg; command arg arg arg; ...
如果你知道它会交替,那么你可以像这样循环遍历args:
for(int i = 1; i < argc; i += 2)
{
//command is argv[i], arg is argv[i + 1]
}
更好的方法是,不是使用命令行参数创建输入提示,而是每行处理一个命令,就像正常的shell使用一样。
答案 3 :(得分:0)
我认为这里的问题是解析argv。
这是一个虚拟逻辑流程:
for(i = 1; i < argc; i++)
{
isCommand = CheckCmd(argv[i]); /* check if argv[i] is a command */
if (isCommand)
{
for(; i < argc; i++)
{
isCommand = CheckCmd(argv[i]); /* check if argv[i] is a command */
if (isNotCommand)
{
PushOption(argv[i]); /* save options */
} else
{
/* Get Command and options from stack */
/* execute command with fork/execv */
}
}
}
}
这里唯一需要的是实现CheckCmd和PushOption / PopOption。