使用execl和fork()在C中创建linux环境
我创建了一个类似于Linux环境的程序。你输入一个命令,它会为你做使用execl和fork()在C中创建linux环境,c,linux,shell,command,exec,C,Linux,Shell,Command,Exec,我创建了一个类似于Linux环境的程序。你输入一个命令,它会为你做 #include <stdio.h> #include <string.h> int main() { int pid; int status; printf("Enter command: "); char s[256]; fgets(s,256,stdin); const char *a[5]; int i = 0; char* token = strtok(s, " "); while(tok
#include <stdio.h>
#include <string.h>
int main()
{
int pid;
int status;
printf("Enter command: ");
char s[256];
fgets(s,256,stdin);
const char *a[5];
int i = 0;
char* token = strtok(s, " ");
while(token)
{
a[i] = strtok(s," ");
i++;
}
while (a[0] != "exit")
{
if(a[0] = "cd")
{
chdir(a[1]);
}
else
{
pid = fork();
if (pid == 0)
{
execvp(a[0],a);
}
if(pid > 0)
{
wait(&status);
}
}
}
return 0;
}
#包括
#包括
int main()
{
int-pid;
智力状态;
printf(“输入命令:”);
chars[256];
fgets(s,256,stdin);
常量字符*a[5];
int i=0;
char*token=strtok(s,“”);
while(令牌)
{
a[i]=strtok(s,“”);
i++;
}
while(a[0]!=“退出”)
{
如果(a[0]=“cd”)
{
chdir(a[1]);
}
其他的
{
pid=fork();
如果(pid==0)
{
execvp(a[0],a);
}
如果(pid>0)
{
等待(&状态);
}
}
}
返回0;
}
它使用标记来分隔命令的参数。我试着运行它,它编译并运行,但没有执行我想要的命令。我认为这可能与它创建代币的方式有关。任何帮助都会很好。谢谢。线路:
a[i] = strtok(s," ");
将a[i]
设置为字符串中的指针,您正在修改该指针,最终可能会删除临时NUL字符(来自strtok
)
您可能想试试:
a[i] = strdup (strtok (s," "));
相反
让我进一步解释。假设我们拥有该命令(因为它存在于内存中): 当您
strtok
it时,它几乎肯定会更改为:
ls\0-al xyzzy\0
^
然后它会给你从strtok返回的s
(用^
表示)并放入a[0]
。下次通过时,它将字符串更改为:
ls -al\0xyzzy\0
^
并提供由^
指示的地址,并将其放入a[1]
中。不幸的是,a[0]
现在指向字符串“ls-al”
最终,字符串将返回其原始状态,指针在指向正确的地址时,不会像预期的那样以null结尾字符串(最后一个除外)
因此,您将以以下方式结束:
a[0] = "ls -al xyzzy"
a[1] = "-al xyzzy"
a[2] = "xyzzy"
通过使用strdup
,您可以创建每个字符串的副本(当字符串如您所期望的那样为单个单词时),该副本随后不会被字符串标记代码中的后续操作修改
但是,请记住,在处理完所有已分配的字符串后,释放它们
您可以将此代码用作基线:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main (void) {
char str[256], *word[20];
int i, num, len;
printf ("Enter command: ");
fgets (str, sizeof (str), stdin);
num = 0;
word[num] = strtok (str, " ");
while (word[num] != NULL) {
word[num] = strdup (word[num]);
len = strlen (word[num]);
if (strlen (word[num]) > 0)
if (word[num][len-1] == '\n')
word[num][len-1] = '\0';
word[++num] = strtok (NULL, " ");
}
for (i = 0; i < num; i++) {
printf ("%d: [%s]\n", i, (word[i] == NULL) ? "<<null>>" : word[i]);
free (word[i]);
}
return 0;
}
此外,比较C字符串的正确方法不是:
if (a[0] = "cd")
因为这会比较地址,即使备份内容相同,地址也可能不同。您应该改为使用以下内容:
if (strcmp (a[0], "cd") == 0)
还有最后一件事,传递给
execvp
的argv[]
数组必须有一个最终终止的空指针。这是合同的一部分,因此您需要确保在调用execvp
之前,while循环while(a[0]!=“exit”)
将永远不会终止。您正在比较指针(内存地址)。您可能需要阅读有关strcmp()的信息
if语句
if(a[0]=“cd”)
似乎也不是我认为您想要做的。您正在将指向“cd”
的指针分配给a[0]
。如果您使用编译器诊断(可能的意图是使用==
而不是=
,这也不会起作用-同样strcmp()
是用于字符串比较的东西)。学习使用类似gdb
的调试器。使用gcc-Wall-g
编译程序。然后清除a[5]
数组(应该更大,或者一些堆分配的数据)。还可以查看小型自由软件外壳的源代码(例如sash
),也可以查看a[0]!=“退出”
可能不是您想要的。使用strcmpstrcmp
。阅读一本好的C编程书确实需要几个小时。然后读一本很好的Linux编程书;花一两天时间阅读(可能在图书馆里)。那么strcmp(a[0],char*string1)
在哪个string1被设置为退出?还有一个用于cd?更简单的strcmp(a[0],“exit”)
如果两个字符串相等,则返回0(字符数组包含完全相同的字符,直到终止NUL
)。我与strcmp
进行了所有比较,但我每次发出命令时都会出现分段错误,包括退出。现在真的是学习如何使用调试器的时候了代码>我输入的任何内容都只会给我一个空行。我将所有比较语句重新命名为strcmp。我不明白你关于执行官的最后几点。
if (a[0] = "cd")
if (strcmp (a[0], "cd") == 0)