Cat命令没有';无法正确使用execvp
1) 我不能在这段代码中使用一些命令,例如:Cat命令没有';无法正确使用execvp,c,ubuntu,unix,C,Ubuntu,Unix,1) 我不能在这段代码中使用一些命令,例如:cat somefile.txt>somefile2.txt 我也不能使用:cat somefile.txt | less 2) 当我使用如下命令:(cd../)(cd./Desktop)然后我想退出程序时,我需要多次执行退出命令:即“如果我使用3个cd命令,我需要3个退出命令来结束程序” 我怀疑我不能使用任何具有如下字符的命令:somefile2.txt,也不能使用:cat somefile.txt | less 在标准shell中,和|是shell
cat somefile.txt>somefile2.txt
我也不能使用:cat somefile.txt | less
2) 当我使用如下命令:(cd../)(cd./Desktop)
然后我想退出程序时,我需要多次执行退出命令:即“如果我使用3个cd命令,我需要3个退出命令来结束程序”
我怀疑我不能使用任何具有如下字符的命令:<\124;
提前谢谢 1) 我不能在这段代码中使用一些命令,如:cat somefile.txt>somefile2.txt,也不能使用:cat somefile.txt | less 在标准shell中,
和|
是shell解释的运算符,而不是命令的参数。因为在这种情况下,shell就是您的程序本身,如果您必须支持这些操作符,那么您需要自己实现适当的重定向。请参阅open()
、pipe()
和dup2()
,对于管道案例,您还需要明智地应用close()
2) 当我使用像:(cd../)(cd./Desktop)这样的命令,然后我想退出程序时,我需要多次执行exit命令“如果我使用3 cd命令,我需要3 exit命令来结束程序”
在
cd
命令的特殊情况下,可以在子进程中分叉并更改目录,但子进程不会终止或执行另一个进程。这样,您就可以运行两个shell副本。在控制返回到启动程序的任何进程之前,您需要退出这两个进程。在这种情况下,您可能希望在不分叉(或等待孩子)的情况下执行chdir
。您的问题是否得到“代码太多”警告?你能把你的例子缩减到一些最小的东西来说明你想用cat做什么以及为什么它在你的程序中不起作用吗?while(line[i]!='\n')i++
是line[]
缺少'\n'
?不清楚你在问什么。你能修改一下这句话吗?“.我应该写和我以前使用的相同数量的退出命令”。另外,如前所述,这是一个MVE:?@chux fgets开始一个我不需要的新空行,所以我用这个删除它loop@SherylHohman当我试图退出程序时,我应该多次写入退出命令“如果我使用cd../command三次,我将使用退出命令三次来关闭终端”(我认为每个exit命令都会退出一个子进程)exec后是否有终止子进程的方法???@MoustafaUsama,一般来说,shell应该允许它启动的子进程正常终止,但您可以尝试通过kill()发送适当的信号来终止子进程
函数。请注意,这两个函数都不适用于您的cd
命令,但是,因为目录更改只影响执行它的进程(您所展示的代码中的子进程)。这就是为什么我建议在这种情况下执行chdir()
。
#define MAX_ARGS 5
// Global Declarations
// Mini Functions
void remove_new_line_char(char line[])
{
int i=0;
while(line[i]!= '\n')
i++;
line[i] = '\0';
}
// Grand Functions
int read_line(char line[])
{
fgets(line, 10000, stdin); // File Get String
remove_new_line_char(line); // Remove New Line Charactere
if (strlen(line) > 512)
{
fprintf(stderr,"The Command exceeded available line length\n");
return 0;
}
if (strcmp(line, "exit") == 0)
exit(0);
return 1;
}
int parse_line(char* args[], char line[])
{
int i=0;
args[i] = strtok(line, " ");
if(args[i] == NULL)
{
printf("Command Line is Empty!\n");
return -1;
}
while (args[i] != NULL)
{
int flag = 0;
if(strcmp(args[i],"&") == 0)
flag = 1;
i++;
args[i] = strtok(NULL, " "); // NULL maintains a static pointer to the previously passed string.
if (args[i] == NULL && flag == 1)
{
args[i-1] = NULL; // Remove & From Argument List and Set Background Flag.
return 1;
}
}
return 0;
}
// Main
int main()
{
char* args[MAX_ARGS]; // Array of Strings
char line[10000]; // String
while(1)
{
printf("Shell> ");
if(read_line(line) == 1) // No Errors
{
int background = parse_line(args, line);
if(background != -1) // Command Line isn't Empty
{
// Fork and Execute
pid_t child_pid = fork();
if(child_pid == 0) // Child
{
if (strcmp(args[0], "cd") == 0 && args[1]!= NULL && args[2] == NULL) // Special Handling For CD
{
//printf("%s\n",args[2]);
int check = chdir(args[1]);
if(check == -1)
fprintf(stderr, "Invalid Directory\n");
}
// Handle if args[1]== NULL, Don't even execvp()
else // Other Functions
{
execvp(args[0], args); // args[0] is actually the command.
fprintf(stderr,"an error occured in execution\n%s\n",strerror(errno));
//fprintf(stderr,"Invalid Instruction\n");
}
}
else // Parent
{
if(background == 0)
waitpid(child_pid, 0);
wait(1000);
}
}
}
}
return 0;
}