我正在编写一个程序来从命令行(linux / unix命令)获取用户输入,并在我的程序中执行它们。
到目前为止我的步骤:
主要问题是,当它执行时,它只执行execv命令中的“bin / ls /”。
以下是运行程序的示例输出:
输入命令数:2
孩子的PID是3487.父母的PID是3485
输入UNIX命令:ls
输入UNIX命令:-al
如果在CMD线上键入“LS”,文件列表
流程完成。
这是我的源代码:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
void main(int argc, char *argv[20])
{
int pid;
int num = 0;
printf("Enter number of commands: ");
scanf("%d", &argc);
pid = fork();
if(pid == 0)
{
printf("Child's PID is %d. Parent's PID is %d\n", (int)getpid(), (int)getppid());
for(num=0; num < argc; num++)
{
printf("Enter a UNIX command: ");
scanf("%s", argv[num]);
}
argv[num+1] = 0;
execv("bin/ls/", argv);
}
else
{
wait(pid);
printf("Process Complete.\n");
exit(0);
}
}
答案 0 :(得分:0)
您的代码存在的一个特定问题是您必须将argv [idx]作为exec的参数传递。你通过argv传递一个char指针数组。
还请注意,argc包含完整的参数计数,并且完整计数包括程序本身。 argv [0]包含要传递参数的程序名称。我没有看到你的for循环反映出来。那就是你正在处理你自己的程序并运行它。
我写这些的方法是在一段时间内遍历argv(或者,如果你愿意的话),使用int变量 - 例如int idx=0;
- 直到我找到一个argv [idx]指针那是空的。
例如,如果你有三个参数,argc将是4,而argv [3]将是你要处理的最后一个参数。 argv [4]将为null。
根据你收到的一些答案,这里有一个discussion的execv和fork。
答案 1 :(得分:0)
更新:
忽略上述第1点和第2点。
man execv:
The execv(), execvp(), and execvpe() functions provide an array of pointers to null-terminated strings that represent the argument list available to the new program. The first argument, by convention, should point to the filename associated with the file being executed. The array of pointers must be terminated by a NULL pointer.
答案 2 :(得分:0)
首先,您要在char* argv[20]
中定义main
,这不是一个好主意。如果您传递的参数超过20个,则会超出数组的范围。
其次,您试图将scanf("%s", argv[num])
的字符串读入到我未能初始化的地址空间中。
当你的程序被调用时,操作系统会初始化argv []数组的“strings”,如果你没有向你的程序传递任何参数,你将没有任何“字符串”,这意味着你将写入你可能不拥有的随机记忆。
如果您真的想按照现在的方式加载命令,请尝试以下操作:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
void main(int argc, char *argv[])
{
int pid;
int num = 0;
int argc2 = 0;
char* argv2[20]; // argv2 will point inside of buffer for convenience.
char* buffer[2000]; // note each array has a limit of 100 characters.
printf("Enter number of commands: ");
scanf("%d", &argc2);
pid = fork();
if(pid == 0)
{
printf("Child's PID is %d. Parent's PID is %d\n", (int)getpid(), (int)getppid());
for(num=0; num < argc2 && num < 20; num++) // your array is 20 long
{
argv2[num] = &buffer[num * 100];
printf("Enter a UNIX command: ");
scanf("%s", argv2[num]);
}
argv[num] = 0; // no need to add + 1 because the for loop did already anyway.
execv("Assignments/ls", argv2);
}
else
{
wait(pid);
printf("Process Complete.\n");
exit(0);
}
}
或者你可以将参数传递给你的主程序,它只是将它们传递给被调用的程序,如下所示:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
void main(int argc, char *argv[])
{
int pid;
int num = 0;
printf("You entered %d commands: \n", argc);
for (num = 0; num < argc; ++num)
{
printf("\t%s\n", argv[num]);
}
pid = fork();
if(pid == 0)
{
printf("Child's PID is %d. Parent's PID is %d\n", (int)getpid(), (int)getppid());
execv("Assignments/ls", &argv[1]);
}
else
{
wait(pid);
printf("Process Complete.\n");
exit(0);
}
}