无效命令的 C++ evecvp 错误处理

c++ evecvp error handling for invalid command

我正在尝试实现一个简单的 shell。除了错误处理,其他一切正常。

当我尝试执行像 "cat ff" 这样的无效命令时,其中 "ff" 不存在,我得到了这个:

预期的行为应该像第三个 "catt f"。它必须以 "ERROR:" 开头,然后是错误消息,这意味着它应该是 "ERROR:cat: ff: No such file or directory"

我应该如何修改我的代码来实现它?提前致谢!

#include <fcntl.h>
#include <iostream>
#include <unistd.h>
#include <cstring>
#include <errno.h>
#include <sys/wait.h>

using namespace std;

int main(){
    int pid;
    int status;
    char *cmd[] = {"cat", "ff", NULL};
    if ((pid = fork()) == 0){
        if (execvp(cmd[0], cmd) == -1){
            cout << "ERROR:" << strerror(errno) << '\n';
        }
    }else if (pid == -1){
        cout << "ERROR:" << strerror(errno) << '\n';
    }else{
        waitpid(pid, &status, 0);
        cout << "Status: " << status << '\n';
    }
}

这里的状态在这里不是很有必要。我只是想弄清楚它是否出现在该错误消息之前。我对此非常陌生,我非常困惑和迷茫。如有不当之处请见谅

第二行cat: ff: No suche file...是cat命令写入stderr管道的错误输出。如果你想抑制它,你需要重定向 stderr 管道。您的 shell 命令 "cat" 执行成功,因此它通过您的最后一个 else 条件处理。你需要在那里检查例如status 256 "no such file" 然后自己打印错误。

#include <fcntl.h>
#include <iostream>
#include <unistd.h>
#include <cstring>
#include <errno.h>
#include <sys/wait.h>
#include <cstdio>

using namespace std;

int main(int argc, char** argv){
    int pid;
    int status;
    char *cmd[] = {"cat", "ff", NULL};
    int pipes[2];
    pipe(pipes);
    if ((pid = fork()) == 0){
        dup2(pipes[1], STDERR_FILENO);
        if (execvp(cmd[0], cmd) == -1){
            cout << "ERROR:" << strerror(errno) << '\n';
        }
    }else if (pid == -1){
        cout << "ERROR:" << strerror(errno) << '\n';
    }else{
        waitpid(pid, &status, 0);
        if(256 == status) {
            cout << "ERROR: ";
            char buffer[100];
            int count = read(pipes[0], buffer, sizeof(buffer)-1);
            if (count >= 0) {
                buffer[count] = 0;
                cout << buffer;
                cout << endl;
            } else {
                cout << "IO Error" << endl;
            }
        } else {
            cout << "Status: " << status << '\n';
        }
    }
}