linux shell 中的管道管理

Pipeline management in linux shell

我目前正在研究如何将流水线管理到 shells。 例如,在我的 shell 中,如果我输入 "ls | wc | less"。此操作的结果将是创建三个进程,ls wc 和 less。 ls 的输出将通过管道传输到 wc 的输入输入,而 wc 的输出将通过管道传输到 less 的输入输入。

对我来说,就是在执行"ls | wc | less"的过程中。 less 的标准输入不会是键盘,而是 wc 的输出。但是,less 仍然会响应我的键盘。为什么 ?我不明白,因为对我来说,less应该对键盘不敏感,因为它已经通过管道传输了。

有人有想法吗? 谢谢

只是一个猜测 - less 正在为交互式会话打开 /dev/console,我用过一次这个技巧。我错了 - strace 是你的朋友 :-):

echo | strace less

) = 16
read(0, "\n", 8192)                     = 1
write(1, "\n", 1
)                       = 1
read(0, "", 8191)                       = 0
write(1, "[7m(END)[27m[K", 17(END)) = 17
read(3, 

如您所见,从 FD 3 读取的数据较少。

/* Standard file descriptors.  */
#define STDIN_FILENO    0   /* Standard input.  */
#define STDOUT_FILENO   1   /* Standard output.  */
#define STDERR_FILENO   2   /* Standard error output.  */

仔细观察(在 'q' 之后)显示:

open("/dev/tty", O_RDONLY)              = 3

确认@123 的源代码检查 - 它打开 /dev/tty

来自less的代码

#if HAVE_DUP
    /*
     * Force standard input to be the user's terminal
     * (the normal standard input), even if less's standard input 
     * is coming from a pipe.
     */
    inp = dup(0);
    close(0);
#if OS2
    /* The __open() system call translates "/dev/tty" to "con". */
    if (__open("/dev/tty", OPEN_READ) < 0)
#else
    if (open("/dev/tty", OPEN_READ) < 0)
#endif
        dup(inp);
#endif

它打开来自 /dev/tty 的直接流以及任何你的标准输入。