加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

自定义简单Shell中的错误’ls’命令行为

发布时间:2020-12-15 21:01:47 所属栏目:安全 来源:网络整理
导读:我遇到的问题似乎只是从我的知识中消失了.我正在编写一个简单的 shell来学习一些用于Unisys实习的系统编程.在我的shell中,似乎我正在尝试的所有命令都在ls之外工作,甚至现在发现了wc命令. ls和wc在我自己输入时工作,但如果我给它参数,它将无法工作并给我一个
我遇到的问题似乎只是从我的知识中消失了.我正在编写一个简单的 shell来学习一些用于Unisys实习的系统编程.在我的shell中,似乎我正在尝试的所有命令都在ls之外工作,甚至现在发现了wc命令. ls和wc在我自己输入时工作,但如果我给它参数,它将无法工作并给我一个错误说没有这样的文件或目录.

这是我的代码:

#include <sys/types.h>
#include <sys/wait.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sysexits.h>
#include <unistd.h>

#define BUF_SIZE 1024
#define DELIMS " -rtn"

/****************************************************************
 *  Capture input from the user. Returns the input from the
 *  standard input file descriptor.
 ***************************************************************/
char * getInput (char **buffer,size_t buflen)
{
    size_t bufsize = BUF_SIZE;
    *buffer = malloc(sizeof(char) * bufsize + 1);   // allocate space for the buffer

    if (!*buffer)
    {
        fprintf(stderr,"Shell: buffer allocation errorn");
        exit(EXIT_FAILURE);
    }

    printf("$$");

    fflush(NULL);

    int bytesRead = getline(&(*buffer),&bufsize,stdin);
    if (bytesRead < 0)
    {
        printf("Getline errorn");
        exit(EXIT_FAILURE);
    }

    return *buffer; // Not capturing return value right now
 }

/****************************************************************
 *  Tokenize the buffer input from stdin
 ***************************************************************/
char ** splitLine(char *line)
{
    int bufsize = BUF_SIZE;
    int pos = 0;
    char **tokens = malloc (sizeof(char) * BUF_SIZE + 1);
    char *token;

    if (!tokens)
    {
        fprintf(stderr,"Shell: buffer allocation errorn");
        exit(EXIT_FAILURE);
    }

    /* Tokenize the line */
    token = strtok(line,DELIMS);
    while (token != NULL)
    {
        tokens[pos] = token;
        pos++;
        if (pos > bufsize)
        {
            bufsize += BUF_SIZE;
            tokens = realloc(tokens,bufsize * sizeof(char) + 1);
            if (!tokens)
            {
                fprintf(stderr,"Shell: buffer allocation errorn");
                exit(EXIT_FAILURE);
            }
        }
        token = strtok(NULL,DELIMS);   // continue grabbing tokens
    }

    tokens[pos] = NULL;
    return tokens;
}

/****************************************************************
 *  Main function
 ***************************************************************/
int main (int argc,char **argv)
{
    char *buf;     // buffer to hold user input from standard input stream.
    pid_t pid;          // Parent id of the current process
    int status;

    /* Loop while the user is getting input */
    while (getInput(&buf,sizeof(buf)))
    {
        char **args = splitLine(buf);
        int i = 0;

        /* Print tokens just to check if we are processing them correctly */
        while (1)
        {
            char *token = args[i++];
            if (token != NULL)
                printf("Token #%d: %sn",i,token);
            else
                break;
        }

        fflush(NULL);

        /* Fork and execute command in the shell */
        pid = fork();
        switch(pid)
        {
            case -1:
            {
                /* Failed to fork */
                fprintf(stderr,"Shell cannot fork: %sn",strerror(errno));
                continue;
            }
            case 0:
            {
                /* Child so run the command */
                execvp(args[0],args);        // Should not ever return otherwise there was an error
                fprintf(stderr,"Shell: couldn't execute %s: %sn   ",buf,strerror(errno));
                exit(EX_DATAERR);
            }
        }

        /* Suspend execution of calling process until receiving a status message from the child process
            or a signal is received. On return of waitpid,status contains the termination
            information about the process that exited. The pid parameter specifies the set of child
            process for which to wait for */
        if ((pid = waitpid(pid,&status,0) < 0))
        {
            fprintf(stderr,"Shell: waitpid error: %sn",strerror(errno));
        }

        free(args);
    }

    free(buf);

    exit(EX_OK);
}

例如,我在输出中尝试了以下命令:

ls -la(问题)

$$ls -la
Token #1: ls
Token #2: la
ls: la: No such file or directory
$$

wc -l(问题)

$$wc -l
Token #1: wc
Token #2: l
wc: l: open: No such file or directory

LS

$$ls
Token #1: ls
Makefile    driver      driver.dSYM main.c      main.o
$$

ps -la

$$ps -la
Token #1: ps
Token #2: la
  UID   PID  PPID CPU PRI NI      VSZ    RSS WCHAN  STAT   TT       TIME COMMAND
    0  2843  2405   0  31  0  2471528      8 -      Us   s000    0:00.08 login 
  501  2845  2843   0  31  0  2463080   1268 -      S    s000    0:01.08 -bash
  501  4549  2845   0  31  0  2454268    716 -      S+   s000    0:00.01 ./driv
    0  4570  4549   0  31  0  2435020    932 -      R+   s000    0:00.00 ps la
$$

哪个

$$which which
Token #1: which
Token #2: which
/usr/bin/which

哪个 – 哪个

$$which -a which 
Token #1: which
Token #2: a
Token #3: which
/usr/bin/which

甚至最后是男人

GETLINE(3)               BSD Library Functions Manual               GETLINE(3)

NAME
     getdelim,getline -- get a line from a stream

LIBRARY
     Standard C Library (libc,-lc)
.
.
.

任何人都可以帮我指出我遇到这个问题的原因吗?

解决方法

您在DELIMS宏中添加了“ – ”作为单词分隔符.

删除它应该可以解决您的问题.

顺便说一下,它可能最好避免宏,你可以轻松地做到这一点.在这里,我会使用const char * delims来存储分隔符.我通常发现更容易声明一个接近其使用位置的变量 – 我认为这样可以更容易地发现错误并阅读代码.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读