【发布时间】:2020-10-21 00:23:56
【问题描述】:
我用 C 语言在 linux 中制作了一个自定义终端,我正在尝试实现末尾的“&”应该在后台执行进程的功能,我制作了一个函数来剪切末尾的“&”有效的行,例如,如果我输入:
root@ivo-Surface-Pro-6:/home/ivo/Documents/SO1/Unix-Shell$echo hola &
返回是:
你好
但如果我尝试执行如下命令:'ls -lt &' 它会返回:
root@ivo-Surface-Pro-6:/home/ivo/Documents/SO1/Unix-Shell$ls -lt &
ls: cannot access '': 没有这样的文件或目录
我的代码如下:
void parseAmp(char *str, char garbage) //Function to see if & is in there and delete it, only if it is last{
char *src, *dst;
int is = 0;
for (src = dst = str; *src != '\0'; src++)
{
*dst = *src;
if (*dst != garbage)
dst++;
}
*dst = '\0';
//dst[strlen(dst) - 1] = '\0'; -> I thought of doing this, but doesnt work either}
int main(){ /* shell loop */
char command[COMMAND_BUFFER_SIZE];
char *tokens[TOKEN_BUFFER_SIZE], *tmp;
char *aux;
int token_Size = 0;
int pid;
int child_pid;
int status;
int result;
int flag;
int check;
int isPipe;
int output;
int input;
int isAmper;
int blk;
signal(SIGINT, handlerC);
signal(SIGTSTP, handlerZ);
signal(SIGQUIT, handlerBS);
signal(SIGCHLD, handlerZomb);
while (1)
{
using_history();
do
{
customPrompt();
fgets(command, COMMAND_BUFFER_SIZE, stdin);
} while (strlen(command) < 2);
token_Size = 0;
token_Size = parse(command, tokens, token_Size);
if (ownCmdHandler(tokens))
{
continue;
}
if ((child_pid = fork()) == -1)
{
perror("Fork:");
exit(1);
}
if (child_pid == 0)
{
isAmper = needs_amper(tokens, token_Size);
output = needs_out_redir(tokens, token_Size);
input = needs_in_redir(tokens, token_Size);
isPipe = needs_pipe(tokens, token_Size);
if (strcmp(tokens[0], "echo") == 0)
{
int i = 1;
for (i; tokens[i]; i++)
{
printf("%s ", tokens[i]);
}
}
flag = 0;
if (output != -1)
{
redirect_output(tokens, output);
tokens[output] = NULL;
flag = 1;
}
if (input != -1)
{
redirect_input(tokens, input);
tokens[input] = NULL;
flag = 1;
}
if (isPipe != -1)
{
create_pipe(tokens, output, input, isPipe);
}
if (isAmper != -1)
{
parseAmp(tokens[isAmper], '&')l
blk = 1;
}
if (flag || isPipe == -1)
{
for (int i = 0; tokens[i]; i++)
{
//printf("Toy: %s ", tokens[i]);
}
execvp(tokens[0], tokens);
perror("Unkown Command:");
exit(1);
}
}
else
{
if (blk == 1)
{
printf("Waiting for child, pid = %d\n", pid);
//result = waitpid(child_id, &status, 0);
}
else
{
pid = wait(&status);
}
}
}
return 0;}
如果“&”被正确删除,我不明白为什么程序会向我抛出该错误,我是否遗漏了什么?我能做些什么来纠正这个问题?
编辑:如果您想知道 need_amper 的作用,它会返回 & 的位置
static int needs_amper(char *tokens[], int size){
int position;
int i;
position = -1;
if (strcmp(tokens[size], "&") == 0)
{
position = size;
}
return position;}
【问题讨论】:
-
我猜在
....SO1/Unix-Shell$echo hola &中,包括$字符在内的所有内容都是来自您的shell 的“提示”?在$和echo 之间留一个空格会更容易阅读,即....SO1/Unix-Shell$ echo hola &当然,这是您的意图。无法解决这个问题的c部分。您是否在调试器中运行它以查看变量正在按照您想要的方式构建和处理?祝你好运! -
这看起来像一个外壳,而不是终端。两者之间存在巨大差异。