ls 输出的行数

how*_*rdh 4 ls wc

ls被调用时,它输出当前目录中的所有文件/目录,尝试在每一行中尽可能多地适应。为什么当传递给 时wc -l,它输出文件数?它如何决定输出结果的行数?

Run*_*ium 11

ls执行它分析各种选项。它还通过isatty()检测输出是否为 tty 。

ls.c:

代码

case LS_LS:
  /* This is for the `ls' program.  */
  if (isatty (STDOUT_FILENO))
    {
      format = many_per_line;
      /* See description of qmark_funny_chars, above.  */
      qmark_funny_chars = true;
    }
  else
    {
      format = one_per_line;
      qmark_funny_chars = false;
    }
  break;
Run Code Online (Sandbox Code Playgroud)

...

代码

      /* disable -l */
      if (format == long_format)
        format = (isatty (STDOUT_FILENO) ? many_per_line : one_per_line);
Run Code Online (Sandbox Code Playgroud)

等等。


如果你愿意,你可以编译一个简单的测试:

isawhat.c

#include <stdio.h>
#include <unistd.h>

int main(void)
{
    if (isatty(STDOUT_FILENO)) {
        fprintf(stdout, "Word by word my world.\n");
    } else {
        fprintf(stdout, "HELP! Stranger handling my words!!\n");
    }

    fprintf(stderr, "Bye bye.\n");

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

编译:

gcc -o isawhat isawhat.c
Run Code Online (Sandbox Code Playgroud)

然后例如:

$ ./isawhat | sed 's/word/world/'
Run Code Online (Sandbox Code Playgroud)

宽度以列测量。一列是一个字符。它以 80 开头,然后检查是否设置了环境变量 COLUMNS 并保存了一个不大于 SIZE_MAX 的有效整数(它依赖于拱形 - 您的终端永远不会那么宽(至少现在还没有))。

尝试例如echo $COLUMNS。它很可能反映了您在窗口中可用的列数。随着窗口调整大小 - 这会得到更新。它很可能也被各种命令重置。

将其设置得更难的一种方法是通过stty. 例如stty columns 60。使用stty -a查看全部(男人的stty)。一个有趣的软件。

如果在其中编译还通过ioctl()查询列,窗口大小检测。. 通过将 stdout的文件编号ioctl传递给TIOCGWINSZ并传递请求,结构winsize将填充列数。

这也可以通过一个简单的 c 代码来演示:

编译、运行和调整窗口大小。应该更新。Ctrl+C 退出。

#include <stdio.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <signal.h>

static int run;

void sig_handler(int sig) {
    switch (sig) {
    case SIGINT:
    case SIGTERM:
    case SIGSTOP:
        run = 0;
        break;
    }
}

void sig_trap(int sig) {
    if ((signal(sig, sig_handler)) == SIG_IGN)
        signal(sig, SIG_IGN);
}

int main(void)
{
    struct winsize ws;

    sig_trap(SIGINT);
    sig_trap(SIGTERM);
    sig_trap(SIGSTOP);

    run = 1;
    while (run) {
        if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) != -1) {
            fprintf(stdout, "\r %s: %3d, %s: %d\r",
                "Columns", ws.ws_col,
                "Rows", ws.ws_row
            );
            fflush(stdout);
        }
        usleep(5000);
    }
    fprintf(stdout, "\n");

    return 0;
}
Run Code Online (Sandbox Code Playgroud)