呼び出されると、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);
など。
必要に応じて簡単なテストをコンパイルできます。
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/'
幅は列単位で測定されます。列は1文字です。開始は80次に、環境変数COLUMNSが設定されていることを確認し、SIZE_MAXより大きくない有効なintを保存します(これはアーチによって異なります。端末は決してそれほど広くはありません(少なくともまだ))。
例を見てくださいecho $COLUMNS
。これは、ウィンドウで利用可能な列の数を反映する可能性が高いです。ウィンドウのサイズが変更されると更新されます。さまざまなコマンドでもリセットされる可能性が高いです。
より困難にする1つの方法は、stty
例えばstty columns 60
。すべてを見るために使用されますstty -a
(man stty)。興味深いソフトウェアです。
コンパイルされている場合は、次のように列を照会することもできます。ioctl()、ウィンドウサイズの検出。。標準出力のファイル番号を渡し、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
。