【问题标题】:Redirecting "command not found" to a file将“找不到命令”重定向到文件
【发布时间】:2019-04-09 06:20:21
【问题描述】:

所以我正在为我正在进行的项目编写代码。它是关于使用文件描述符重定向输入输出和错误。但是错误重定向存在问题。如果我在命令行中,我通常会使用以下命令:

    lsa >& out

此命令将作为回报向“out”文件写入一条错误消息,说明“bash: lsa: command not found”

在我的项目中,我是这样做的:

    ./proj ls GTAMP out

错误被重定向到“输出”文件,但它将是: "lsa: 没有这样的文件或目录"

以下是我的做法

    //Before Child
    int stdin = dup(0);
    int stdout = dup(1);
    int stderr = dup(2);

            printf("GTAMP\n");
            int fderr = open(argv[argc-1], O_WRONLY | O_CREAT | O_TRUNC, 0666);
            dup2(fderr,2);
            dup2(fderr,1);
            close(fderr);
    //In child
    returnVal= fork();  
    if(returnVal==0)
    {
    char *args[] = {argv[2],argv[3],argv[4],NULL};                
                    execvp(argv[2], args);
                    perror(argv[2]);
                    exit(errno);
    }
    //In Parent
        wait(NULL);
        dup2(stdin,0);
        dup2(stdout,1);
        dup2(stderr,2);
        printf("\nCommand(s) execution complete.\n");
        return 0;

【问题讨论】:

  • 对,“command not found”来自bash,你没有使用bash;如果您想编写自己的错误消息(如 bash 那样),则需要编写执行此操作的代码。这里有什么问题?
  • 所以除了使用 printf 对其进行硬编码之外,没有其他方法可以调用“找不到命令”错误吗?或者是否有替代方法可以传递 perror 或其他一些策略,可以将“ No such file or directory”替换为“: Command not found”?
  • 看bash的源码;你会看到msgid "%s: command not found"在它的翻译表中,通过internal_error (_("%s: command not found"), pathname);调用

标签: bash command-line-arguments stderr


【解决方案1】:

“command not found”不是操作系统级别的错误——正如您在代码中演示的那样,这些错误是通过使用perror() 查找与当前errno 关联的字符串来查找的。

相反,像 bash 这样的 shell 实际上对字符串 command not found 进行了硬编码。引用实现(execute_cmd.c,来自 bash-20180420 快照):

          hookf = find_function (NOTFOUND_HOOK);
          if (hookf == 0)
            {
              /* Make sure filenames are displayed using printable characters */
              pathname = printable_filename (pathname, 0);
              internal_error (_("%s: command not found"), pathname);
              exit (EX_NOTFOUND);       /* Posix.2 says the exit status is 127 */
            }

为了与另一个 shell 进行比较,dash 不会发出 foo: command not found,而只是发出 foo: not found;这是通过src/error.c 中的errmsg 函数构造的,从src/exec.c 中的shellexec 函数调用:

    exerror(EXEND, "%s: %s", argv[0], errmsg(e, E_EXEC));

...调用...

const char *
errmsg(int e, int action)
{
    if (e != ENOENT && e != ENOTDIR)
        return strerror(e);

    if (action & E_OPEN)
        return "No such file";
    else if (action & E_CREAT)
        return "Directory nonexistent";
    else
        return "not found";
}

简而言之:在这两个 shell 中,字符串“command not found”都不起源于 shell 本身的源代码之外的任何地方。如果您希望自己的 shell 编写该错误,您应该编写必要的代码来实现它。

【讨论】:

    猜你喜欢
    • 2020-03-12
    • 1970-01-01
    • 2018-06-07
    • 1970-01-01
    • 2015-10-30
    • 1970-01-01
    • 1970-01-01
    • 2012-09-28
    • 1970-01-01
    相关资源
    最近更新 更多