【发布时间】:2019-03-26 01:30:23
【问题描述】:
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <string.h>
#include <sys/wait.h>
#include <unistd.h>
#include <readline/readline.h>
#include <readline/history.h>
HIST_ENTRY;
void printPrompt()
{
printf("SB> ");
}
char *readCommandLine()
{
char* myComm = (char*)malloc(1024);
scanf("%s", myComm);
return myComm;
}
char *parseCmd(char *myComm, char **tokens, size_t *index)
{
char *tok;
const char *delim = " ";
*index = 0;
if (tok != NULL)
{
tokens[*index] = tok;
(*index)++;
}
else
{
tokens[*index] = "\0";
printf("%s\n", tok);
return;
}
while(tok != NULL)
{
tok = strtok(NULL, delim);
tokens[*index] = tok;
(*index)++;
}
tokens[*index] = NULL;
return myComm;
}
int isInternalCommand(char *c)
{
int value = 0;
if (strcmp(c, "exit") == 0)
{
value = 1;
printf("%s\n", "yes");
}
return value;
}
void execInternalCommand(char *c)
{
int val = 0;
char a[4];
if (strcmp(c,"exit") == 0)
{
val = val + 1;
}
switch(val)
{
case 1:
_exit(0);
break;
default:
break;
}
}
void executeCommand (char * c, char * const arguments)
{
execvp(c, arguments);
}
int main()
{
char *myComm;
char *parsed;
size_t num_args = 100;
char **tokens = malloc(sizeof(char *) * (num_args+1));
size_t *idx = (size_t *) malloc(sizeof(size_t));
pid_t pid, cpid;
int *status;
while(1)
{
printPrompt();
myComm = readCommandLine();
parsed = parseCmd(myComm, tokens, idx);
char *const *args = tokens;
if (isInternalCommand(parsed))
{
execInternalCommand(parsed);
}
else
{
pid = fork();
if (pid == 0)
{
executeCommand(parsed, args);
printf("%s\n", "executing...");
}
else if (pid > 0)
{
waitpid(cpid, &status, 0);
printf("%s\n", "waiting...");
}
else
{
}
}
free(idx);
}
return 0;
}
所以,每当我尝试解析命令时,它只适用于单字命令。 例如,每当我尝试 mkdir ./something 时,它都会显示带有“缺少操作数”的 mkdir,这意味着它不会创建目录。此外,每当我键入 man 某些内容时,例如 man exec,它会告诉您“您想查看哪个手册页?”之类的内容。我该如何解决这个问题?看起来这是一个解析问题。
【问题讨论】:
-
如果您的程序的目的不是参数解析而是其他东西,并且 arg 解析正在进行中,我建议使用 argp 或其他一些现有的解析实用程序。
-
或(创可贴)
if (scanf("%1023[^\n]", myComm) != 1) /* handle error */,但请注意stdin中的尾随'\n'将未读。 (注意: 这是在您验证myComm != NULL以验证分配之后)请参阅:scanf(3) - Linux manual page