首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >自编壳问题

自编壳问题
EN

Stack Overflow用户
提问于 2020-10-21 00:23:56
回答 1查看 47关注 0票数 1

我用C语言在linux中创建了一个自定义终端,我试图实现一个函数,其中'&‘应该在后台执行进程,我创建了一个函数来在行的末尾删除'&’,例如,如果我输入:

root@ivo-Surface-Pro-6:/home/ivo/Documents/SO1/Unix-Shell$echo hola &

回报是:

hola

但是,如果我试图执行一个命令,如:‘it -lt &’,它将返回:

root@ivo-Surface-Pro-6:/home/ivo/Documents/SO1/Unix-Shell$ls

-lt &

ls:无法访问“”:没有这样的文件或目录

我的代码如下:

代码语言:javascript
复制
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;}

我不明白为什么程序会抛给我这个错误,如果“&”被正确删除了,我是不是遗漏了什么?我能做些什么来纠正这个问题?

编辑:如果您想知道needs_amper做什么,它会返回以下位置&

代码语言:javascript
复制
static int needs_amper(char *tokens[], int size){
int position;
int i;

position = -1;
if (strcmp(tokens[size], "&") == 0)
{
    position = size;
}

return position;}
EN

回答 1

Stack Overflow用户

发布于 2020-10-21 00:58:24

我设法修复了这个问题,这是可行的:因为isAmper返回'&‘is的位置,所以我做到了:

代码语言:javascript
复制
tokens[isAmper] = NULL;

由于execvp正在读取最后一行中的空字符,所以它没有识别它,因此需要在char末尾使用空字符。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64454984

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档