ls가 출력하는 라인 수

ls가 출력하는 라인 수

호출되면 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/'

너비는 열 단위로 측정됩니다. 열은 하나의 문자입니다.시작은 80그런 다음 환경 변수 COLUMNS가 설정되어 있는지 확인하고 SIZE_MAX보다 크지 않은 유효한 int를 저장하십시오(이것은 아치에 따라 다릅니다. 터미널은 결코 그렇게 넓지 않습니다(적어도 아직은)).

예를 들어보십시오 echo $COLUMNS. 이는 창에서 사용 가능한 열 수를 반영할 가능성이 높습니다. 창 크기가 조정되면 업데이트됩니다. 다양한 명령으로도 재설정될 가능성이 높습니다.

더 어렵게 만드는 한 가지 방법은 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.

관련 정보