簡體   English   中英

在shell中運行cat命令時文件描述符錯誤

[英]Bad file descriptor when running cat command in a shell

我正在嘗試在要為類似Unix的OS(xV6)編寫的外殼中實現I / O重定向。 在我為操作系統閱讀的手冊中,我發現以下代碼將在shell中運行以執行cat命令:

char *argv[2];
argv[0] = "cat";
argv[1] = 0;
if(fork() == 0) {
    close(0);
    open("input.txt", O_RDONLY);
    exec("cat", argv);
}

我修改了代碼以使其在具有argv數組的外殼程序中運行,該外殼程序位於另一個函數中,但它保留了該功能。 由於某些原因,當我運行cat < input.txt ,shell輸出:

cat: -: Bad file descriptor
cat: closing standard input: Bad file descriptor

我仍然是OS編程的新手,所以我對I / O重定向的所有功能尚不完全清楚,但是我認為我擁有的代碼應該可以使用。 是什么引起了問題。 我在下面有I / O重定向的代碼:

case '<':
    ecmd = (struct execcmd*)cmd;
    rcmd = (struct redircmd*)cmd;

    if(fork() == 0){
      close(0);
      open("input", O_RDONLY);
      execvp(ecmd->argv[0], ecmd->argv );
    }
    runcmd(rcmd->cmd);
    break;

編輯

我做了strace -e open ls並得到:

open("/etc/ld.so.cache",    O_RDONLY|O_CLOEXEC) = 3
open("/lib/x86_64-linux-gnu/libselinux.so.1", O_RDONLY|O_CLOEXEC) = 3
open("/lib/x86_64-linux-gnu/libacl.so.1", O_RDONLY|O_CLOEXEC) = 3
open("/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
open("/lib/x86_64-linux-gnu/libpcre.so.3", O_RDONLY|O_CLOEXEC) = 3
open("/lib/x86_64-linux-gnu/libdl.so.2", O_RDONLY|O_CLOEXEC) = 3
open("/lib/x86_64-linux-gnu/libattr.so.1", O_RDONLY|O_CLOEXEC) = 3
open("/proc/filesystems", O_RDONLY)     = 3
open("/usr/lib/locale/locale-archive", O_RDONLY|O_CLOEXEC) = 3
a.out  sh.c  test
+++ exited with 0 +++

編輯2

由於某種原因,這種情況下的代碼有效,但是我不確定為什么:

case '<':
    rcmd = (struct redircmd*)cmd;
    close(rcmd->fd);
    if(open(rcmd->file, rcmd->mode) < 0){
      printf(2, "Cannot open file %s\n", rcmd->file);
      perror(rcmd->file);
      exit(1);
    }
    runcmd(rcmd->cmd);
    break;

您不能只關閉stdin然后打開另一個文件。 它不會自動成為您的新標准輸入。 您要使用的是syscall dup2,它可以將文件描述符“重定向”到另一個文件描述符。

int fd = open("input.txt", O_RDONLY);
dup2(fd, 0); // stdin now points to fd
close(fd);

有關更多信息,請參見man 2 dup2 請注意,open和dup2都可能失敗,因此,如果您對此感到擔憂,則應檢查它們的返回值。

編輯 :這有時實際上會工作,因為POSIX保證內核將始終分配最低的空閑文件描述符。 但是它不是線程安全的,並且通常只是不好的樣式。 我建議始終執行dup2,即使在某些情況下,如果沒有它,您可能會逃脫。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM