【发布时间】:2015-12-14 15:33:25
【问题描述】:
所以,我必须构建一个自定义 shell,它可以执行所有 sh 命令和位于 /usr/bin 中的所有二进制文件以及 shell 中包含的其他二进制文件,但我目前无法使用 inbuild cd 并且不知道如何即使通过 chdir 也能正常工作(我尝试了多次,但如果 chdir 在循环内,它将为每个 shell 重新创建一个 fork)。
如果你能在我是学生的时候帮助我并给我一些提示和建议,那就太好了。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "color.h"
int expertShell()
{
while(1)
{
FILE *fp;
char path[1035], command[1024];
printf(ANSI_COLOR_BLUE "☁ " ANSI_COLOR_RESET);
fgets(command, sizeof(command)-1, stdin);
if(strncmp(command, "cd", 2) == 0)
{
chdir(strtok(command, "cd "));
}
if(strncmp(command, "exit", 4) == 0)
{
exit(1);
}
if(strncmp(command, "ls", 2) == 0)
{
strcat(strtok(command,"\n"), " --color=always");
}
if(strncmp(command, "nano", 4) == 0 || strncmp(command, "vi", 2) == 0)
{
system(command);
}
else
{
fp = popen(command, "r");
if (fp == NULL) {
printf("Failed to run command\n" );
exit(1);
}
while (fgets(path, sizeof(path)-1, fp) != NULL) {
printf("%s", path);
}
pclose(fp);
}
}
}
【问题讨论】:
-
为什么不在
command中添加绝对路径作为前缀并传递给popen()调用。您的文件中也缺少#include <unistd.h>。 -
不需要绝对路径作为前缀,实际上,问题在于 shell 不会更改目录,因为 popen 正在创建另一个分叉,对于 unistd.h 它是固定的
-
这个问题与
popen()forking 一个孩子无关。子进程将在父进程的cwd中生成。问题在于chdir()未能更改为不存在的目录。获取不正确目录的根本原因在于fgets()。变量command以\n结束。如果您在fgets()之后添加此行command[strlen(command)-1]=0;,它将用\0替换\n。然后chdir()将工作,popen()将在正确的目录中运行。 -
@alvits 哦,完全忘记了 chdir 在有 \n 且没有行尾标识符时无法打开,谢谢伙计;)