如何让我的C外壳认识到这是命令?

发布于 2025-01-22 12:22:25 字数 1962 浏览 4 评论 0原文

我在C上很新,但目前正在努力创建C程序以充当外壳接口。它应该接受命令,然后在单独的过程中执行每个命令。目前,我被困在试图让C认识到这是命令。我不确定该怎么做,似乎找不到任何有用的例子。

这是我的代码,它说的一切都不是有效的命令(“否CMD”)。有人知道为什么会发生这种情况吗? C是否无法识别它是execvp()函数中的命令,还是我需要为该特定目的实现某些内容?

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

#define MAX_LINE 80
/* 80 chars per line per command */

int main(void) {
  //char *args[MAX_LINE/2 + 1];
    char *args = calloc(MAX_LINE, (MAX_LINE/2 +1));
    const size_t sz = MAX_LINE;
    pid_t pid;
  /* command line (of 80) has max of 40 arguments*/
  int should_run = 1;

  while (should_run) {
    printf("osh>"); //beginning of command line
        fgets(args, sz, stdin); //gets the stdin

        char *token = strtok(args, " \n"); //supposed to break str if it has a space or line and recognize there are 2 commands
        printf("%s\n", token);
        
        token = strtok(NULL," \n");
        printf("%s\n", token);
            pid_t parent = getpid();
      pid = fork(); //forking child
            if(pid == 0){ //if forking occurred
                int status = execvp(&args[0], &args); //status of input, is it a command?
                printf("%d", status);
                printf("forked!");
                if(status == -1) { //if cmd err, print
                    printf("no cmd");
                    return 1;
                } else {
                    printf("line will be printed");
                }
                return 0;
            }
        fflush(stdout); //flush
        /*

   
    * After reading user input, the steps are :
    * 1: fork a child process
    * 2: the child process will invoke execvp()
    * 3: parent process waits for the child to exit before       
    continuing
    */
  }

  exit(0);
  /**
  return to the operating system:
    -exit this process
    -flush all
  */

  
}

I am very new at C but am currently working on creating a C program to serve as a shell interface. It is supposed to accept commands and then execute each command in a separate process. I am currently stuck trying to get C to recognize that it is a command. I am unsure how to do this, and can't seem to find any useful examples.

Here is my code, it is saying that everything is not a valid command ("no cmd"). Does anyone have any idea why this would be occurring? Is C not able to recognize it is a command in the execvp() function or do I need to implement something for that specific purpose?

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

#define MAX_LINE 80
/* 80 chars per line per command */

int main(void) {
  //char *args[MAX_LINE/2 + 1];
    char *args = calloc(MAX_LINE, (MAX_LINE/2 +1));
    const size_t sz = MAX_LINE;
    pid_t pid;
  /* command line (of 80) has max of 40 arguments*/
  int should_run = 1;

  while (should_run) {
    printf("osh>"); //beginning of command line
        fgets(args, sz, stdin); //gets the stdin

        char *token = strtok(args, " \n"); //supposed to break str if it has a space or line and recognize there are 2 commands
        printf("%s\n", token);
        
        token = strtok(NULL," \n");
        printf("%s\n", token);
            pid_t parent = getpid();
      pid = fork(); //forking child
            if(pid == 0){ //if forking occurred
                int status = execvp(&args[0], &args); //status of input, is it a command?
                printf("%d", status);
                printf("forked!");
                if(status == -1) { //if cmd err, print
                    printf("no cmd");
                    return 1;
                } else {
                    printf("line will be printed");
                }
                return 0;
            }
        fflush(stdout); //flush
        /*

   
    * After reading user input, the steps are :
    * 1: fork a child process
    * 2: the child process will invoke execvp()
    * 3: parent process waits for the child to exit before       
    continuing
    */
  }

  exit(0);
  /**
  return to the operating system:
    -exit this process
    -flush all
  */

  
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

冷月断魂刀 2025-01-29 12:22:25

如果您查看exec函数系列的文档,您会注意到,仅当exec失败时,功能才返回。这是因为exec成功时,用调用程序完全替换了调用过程。

您需要做的是,从父级进程(即获得从fork>的正值),通过waitpid等待子进程。

pid_t pid;

pid = fork();
if ( pid < 0 ) {
    // Handle the error.
}
else if ( pid == 0 ) {
    execvp(&args[0], &args);
    // The fact that we've reached this line means that execvp failed.
    exit(1);
}
else {
    int status;

    while ( waitpid(pid, &status, 0) != pid ) {} // We need this loop in case waitpid gets interrupted by a signal.

    // status doesn't equal the return value of the child process.  We need to extract that with macros.
    if ( WIFEXITED(status) ) {
        printf("Child process exited with code %i\n", WEXITSTATUS(status));
    }
    else {
        printf("Child process was terminated by signal number %i\n", WTERMSIG(status));
    }
}

If you look at the documentation for the exec family of functions, you'll note that the functions only return if the exec failed. That's because exec, when successful, completely replaces the calling process with the invoked program.

What you need to do is, from the parent process (i.e., the one that got a positive value returned from fork), wait on the child process via waitpid.

pid_t pid;

pid = fork();
if ( pid < 0 ) {
    // Handle the error.
}
else if ( pid == 0 ) {
    execvp(&args[0], &args);
    // The fact that we've reached this line means that execvp failed.
    exit(1);
}
else {
    int status;

    while ( waitpid(pid, &status, 0) != pid ) {} // We need this loop in case waitpid gets interrupted by a signal.

    // status doesn't equal the return value of the child process.  We need to extract that with macros.
    if ( WIFEXITED(status) ) {
        printf("Child process exited with code %i\n", WEXITSTATUS(status));
    }
    else {
        printf("Child process was terminated by signal number %i\n", WTERMSIG(status));
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文