从用户输入获取shell命令并执行C程序
目前正在开发接收 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 .....
有什么建议吗?
currently working on program which recieves input command for linux shell and executing them creating child process.
#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;
}
Works with input like ./program command arg
but needed to receive various commands with args for example : ./program command arg command arg .....
Any suggestions?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
shell 是一个复杂的软件,我最近必须为操作系统类实现一个 shell,这很困难;我们只需控制每个输入的一个命令(尽管我们还必须实现 I/O 重定向和管道,并且必须手动进行路径搜索,然后使用 execv() 执行)。
您将遇到的问题在于,实际上没有任何方法可以判断命令行参数数组中的下一个 arg 字符串是命令还是前一个命令的参数。区分命令及其参数的唯一方法是,如果您知道它将交替
command arg command arg ...
,或者每个参数有一些其他标准化数量命令(这不是很有用)或在命令之间有一个分隔符,如分号:command arg;命令 arg arg arg; ...
如果您知道它会交替,那么您可以像这样循环遍历参数:
更好的方法是使用命令行参数创建来代替输入提示符然后每行处理一个命令,就像正常的 shell 使用一样。
A shell is a complex piece of software, I recently had to implement one for an Operating Systems class and it was difficult; and we only had to control one command per input (though we did also have to implement I/O redirection, and piping, and had to do path searching manually then execute with
execv()
).The problem you are going to have lies in that there really isn't any way to tell if the next arg string in the array of command line parameters is a command or argument to a previous command. The only ways that you can differentiate commands and their args is if you know that it will alternate
command arg command arg ...
, or have some other standardized number of arguments per command (which isn't very useful) or have a deliminator between commands like a semicolon:command arg; command arg arg arg; ...
In the case that you know it will alternate then you can just loop through the args like so:
A better way to do this, would be instead of using command line parameters create an input prompt then process one command per line, just like normal shell usage.
您实际上并没有说出您的问题是什么,但我的猜测是您在计算每个分叉进程将如何使用参数时遇到问题。
我猜你所做的是每次分叉时都需要将 argv 指针前进到下一个命令/arg 对。当命令是零终止符时,该分叉循环终止。
我希望我已经理解了你的问题,因为你实际上并没有说明你陷入了这个问题的哪一方面。
You don't actually say what your problem is, but my guess is that you are having problems working out how each forked process will consume the parameters.
I guess what you do is that each time you fork you need to advance the
argv
pointer to the next command/arg pair. This forking loop terminates when the command is the zero terminator.I hope I have understood your question because you haven't actually stated what aspect of this problem you are stuck on.
argc
告诉您argv
的大小,您需要使用该信息从
argv
中提取它们。请注意,这并不能解决具有不同参数数量的命令的问题。
为此原因进行编辑以回复评论:
您可以查看
getopt()
,它允许您执行此操作:问题是您需要能够区分您的命令/参数集。
getopt()
至少可以让你完成一半,然后你只需要解析每个集合。尽管这确实有点矫枉过正,因为这是您唯一的输入类型。在这种情况下,迭代 argv 也同样容易。另一种选择是用分隔符分隔它们:
您需要迭代 argv 并查找逗号以了解命令/arg 集是否完整。或者将所有 argv 连接成一个字符串并使用
strtok()
。恕我直言,有点丑,但可行。argc
tells you the size ofargv
You'd need to extract them from
argv
using that info.Note that this doesn't solve the problem of commands with different numbers of args.
Edit for that reason in reply to comments:
You can look at
getopt()
which would allow you to do this:The problem is you need to be able to differentiate between your command/arg sets.
getopt()
would at least get you half way there, then you just need to parse each set. Though it's really overkill since that's your only input type. Iterating throughargv
would be just as easy in this case.Another option would be to separate them with a delimiter:
You'd need to iterate through
argv
and look for the comma to know a command/arg set was complete. Or concat all of argv into a string and usestrtok()
. Kinda ugly IMHO but doable.我认为这里的问题是解析argv。
这是一个虚拟的逻辑流程:
这里唯一需要的是实现 CheckCmd 和 PushOption/PopOption。
I think the question here is parsing argv.
Here is a dummy logical flow:
The only thing you need here is to realize CheckCmd and PushOption/PopOption.