从用户输入获取shell命令并执行C程序
目前正在开发一个程序,该程序接收LinuxShell的输入命令并执行它们,创建子进程从用户输入获取shell命令并执行C程序,c,linux,fork,execvp,C,Linux,Fork,Execvp,目前正在开发一个程序,该程序接收LinuxShell的输入命令并执行它们,创建子进程 #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
#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,但需要接收带有arg的各种命令,例如:./program command arg command arg
有什么建议吗?您实际上并没有说您的问题是什么,但我的猜测是,您在计算每个分叉进程将如何使用参数时遇到了问题 我猜您要做的是,每次fork时都需要将argv指针前进到下一个命令/arg对。当命令为零终止符时,此分叉循环终止 我希望我已经理解了你的问题,因为你还没有真正说明你在这个问题的哪个方面遇到了麻烦。argc告诉你argv的大小 您需要使用该信息从argv中提取它们 请注意,这并不能解决具有不同参数数的命令的问题 因此,在回复评论时编辑: 您可以查看getopt,它允许您执行以下操作:
./program -c "command arg1 arg2" -c "command arg1" ...
问题是您需要能够区分命令集/参数集。getopt至少可以让您达到一半,然后您只需要解析每个集合。虽然这真的太过分了,因为那是你唯一的输入类型。在这种情况下,通过argv进行迭代也同样容易
另一种选择是使用分隔符分隔它们:
./program command arg1, command arg1 arg2, ...
您需要遍历argv并查找逗号,才能知道命令/arg集已完成。或者将所有argv转换成字符串并使用strtok。有点难看,但可行 shell是一个复杂的软件,我最近不得不为一个操作系统类实现一个,这很困难;我们只需要控制每个输入一个命令,尽管我们还必须实现I/O重定向和管道,并且必须手动执行路径搜索,然后使用execv执行 您将遇到的问题在于,实际上没有任何方法来判断命令行参数数组中的下一个arg字符串是否是前一个命令的命令或参数。区分命令及其参数的唯一方法是,如果您知道它将替换命令arg command arg…,或者每个命令都有一些其他标准化的参数数量,这些参数不是很有用,或者在命令之间有一个分号之类的消除器:command arg;命令arg arg 如果您知道它将交替,那么您可以像这样在arg中循环:
for(int i = 1; i < argc; i += 2)
{
//command is argv[i], arg is argv[i + 1]
}
更好的方法是,不要使用命令行参数,而是创建一个输入提示符,然后每行处理一个命令,就像正常的shell用法一样。我认为这里的问题是解析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。但是我想让用户使用任意数量的带参数的命令,当然我必须改变这一点,如果argc>2,但在不知道用户想要输入的命令数量的情况下,我不知道如何处理。你要么需要将它们作为单个命令传入,引用的参数,例如../program command arg arg command2 arg arg arg,然后解析每个字符串,或者使用一个分隔符,让您知道一个命令/arg集何时完成并实际遍历arg。。。你也许可以用getopt做这件事,已经有一段时间了。。。看起来,我还有其他方法来处理while,比如:`while1{printfShell->;getsline;printf\n;parseline,argv;if strcmpargv[0],exit==0 exit0;executeargv;}“但这样看起来就像一个shell,但我假装用户可以在同一行中使用args执行各种命令。