C 在 bash 中读取 : stdin and stdout

标签 c bash ubuntu buffer

我有一个带有读取功能的简单 C 程序,但我不明白输出结果。

//code1.c
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
int main()
{

    int r;
    char c; // In C, char values are stored in 1 byte

    r = read ( 0, &c, 1);

    // DOC:
    //ssize_t read (int filedes, void *buffer, size_t size)
    //The read function reads up to size bytes from the file with descriptor filedes, storing the results in the buffer.
    //The return value is the number of bytes actually read.

    // Here:
    // filedes is 0, which is stdin from <stdio.h>
    // *buffer is &c : address in memory of char c
    // size is 1 meaning it will read only 1 byte

    printf ("r = %d\n", r);

    return 0;
}

结果截图如下:

Screenshot of program executio

如上所示,我运行了该程序 2 次,第一次尝试输入“a”,第二次尝试输入“aecho hi”。

我如何尝试解释结果:

  1. read 被调用时,它发现 stdin 已关闭并打开它(从我的角度来看,为什么?它应该只是读取它。我不知道它为什么打开它)。
  2. 我在 bash 中输入“aecho hi”,然后按回车键。
  3. read 优先处理 stdin 并读取“aecho hi”的第一个字节:“a”。
  4. 我得到确认,read 已使用 printf 处理了 1 个字节。
  5. a.out 已完成并终止。
  6. stdin 中的剩余数据以某种方式在 bash(我的程序之父)中处理并转到执行它的 stdout 并且由于某种原因第一个字节已被 read 删除。

这都是假设性的,而且非常模糊。非常欢迎任何帮助理解正在发生的事情。

最佳答案

当您在终端模拟器上键入时,它会将您的击键写入一个"file",在本例中是一个内存缓冲区,由于文件系统,它看起来就像磁盘上的任何其他文件一样。

每个进程从其父进程继承 3 个打开的文件句柄。我们在这里对其中之一感兴趣,标准输入。由终端仿真器执行的程序(此处为 bash )作为其标准输入给出了第一段中描述的内存缓冲区。

a.out , 当由 bash 运行时,接收这个相同的文件作为它的标准输入。请记住这一点:basha.out正在从同一个已打开的文件中读取。

在你运行 a.out 之后, 它的 read block ,因为它的标准输入是空的。当您键入 aecho hi<enter> ,终端将这些字符写入缓冲区( <enter> 成为单个换行符)。 a.out只请求一个字符,所以它得到a并将其余字符留在文件中。 (或者更准确地说,在读取 e 之后,文件指针仍然指向 a。)

a.out 之后完成,bash尝试从同一个文件中读取。通常,文件为空(即文件指针位于文件末尾),因此 bash block 等待另一个命令。但是,在这种情况下,已经有可用的输入:echo hi\n . bash现在阅读它就像您在 之后输入它一样 a.out完成。

关于C 在 bash 中读取 : stdin and stdout,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41209541/

相关文章:

c - 无穷大和 nan 值

linux - 如何在 bash if/else 中使用双重 grep 比较?

linux - 比较为数值。 unix

ubuntu - 访问 minikube 仪表板 - (Ubuntu20.04 服务器)VM 在 Windows 10 主机上运行,​​带有 VirtualBox 6.1

javascript - 找不到 PhantomJS 的故障转储

Python 看不到使用 apt-get 安装的模块

C 函数在返回时更改值。损坏的堆栈?

我可以检查是否设置了 Union-Member 吗?

c - 哪一个是好的做法 : using block of code in main or making function of same code?

bash - plistbuddy - 如何拦截错误( key 不存在)