调用时ls
,它输出当前目录中的所有文件/目录,尝试在每行上容纳尽可能多的文件/目录。为什么当传递给 时wc -l
,它会输出文件数?它如何决定将结果输出到多少行?
答案1
ls
执行时它会解析各种选项。它还检测输出是否为 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;
...
/* disable -l */
if (format == long_format)
format = (isatty (STDOUT_FILENO) ? many_per_line : one_per_line);
ETC。
如果你愿意,你可以编译一个简单的测试:
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;
}
编译通过:
gcc -o isawhat isawhat.c
然后例如:
$ ./isawhat | sed 's/word/world/'
宽度以列为单位进行测量。一列是一个字符。开头是 80,然后检查环境变量 COLUMNS 是否已设置并保存一个不大于 SIZE_MAX 的有效 int (这是依赖于 arch 的 - 你的终端永远不会那么宽(至少现在还不是))。
尝试例如echo $COLUMNS
。它很可能反映了窗口中可用的列数。随着窗口大小的调整 - 这会更新。它很可能也会被各种命令重置。
将其设置得更难的一种方法是通过stty
.例如stty columns 60
。用于stty -a
查看全部 (man stty)。一个有趣的软件。
如果在其中编译,还可以通过以下方式查询列读写控制(),窗口大小检测。。通过传递标准输出的文件号ioctl
并传递请求蒂奥克·温兹该结构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;
}
答案2
当输出定向到终端以外的文件描述符(例如管道或文件等)时,ls
其行为就像被调用为ls -1
.