쉘 내장 명령에 적절한 매뉴얼 페이지가 없는 이유는 무엇입니까?

쉘 내장 명령에 적절한 매뉴얼 페이지가 없는 이유는 무엇입니까?

모든 쉘 내장 기능은 동일한 매뉴얼 페이지를 공유합니다.

BUILTIN(1)                BSD General Commands Manual               BUILTIN(1)

NAME
     builtin, !

등.

그런 다음 쉘 내장 명령이 무엇인지 설명하는 짧은 단락과 다음과 유사한 목록이 있습니다.

  Command       External    csh(1)    sh(1)
       !             No          No        Yes
       %             No          Yes       No

하지만 이렇게 하면 man grep다음과 같은 결과가 나옵니다.

  • 곤충
  • 역사
  • 당신은 또한 볼 수 있습니다
  • 기준
  • 설명하다

등.

쉘 내장 함수에는 -A또는와 같은 자체 기록, 설명 및 매개 변수가 없습니까 -r? 매뉴얼 페이지에 이러한 내용이 제공되지 않는 이유는 무엇이며 이를 정확하고 효율적으로 사용하는 방법을 어떻게 배울 수 있습니까?

답변1

내장 함수는 쉘의 일부이기 때문입니다. 그들이 가지고 있는 모든 오류나 기록은 쉘 자체의 것입니다. 이는 독립 실행형 명령이 아니며 빌드된 셸 외부에 존재하지도 않습니다.

적어도 이에 상응하는 것은 명령 bash입니다 . help예를 들어:

$ help while
while: while COMMANDS; do COMMANDS; done
    Execute commands as long as a test succeeds.

    Expand and execute COMMANDS as long as the final command in the
    `while' COMMANDS has an exit status of zero.

    Exit Status:
    Returns the status of the last command executed.

모든 bash 내장 기능에는 help페이지가 있습니다. 그 자체 도 help:

$ help help
help: help [-dms] [pattern ...]
    Display information about builtin commands.

    Displays brief summaries of builtin commands.  If PATTERN is
    specified, gives detailed help on all commands matching PATTERN,
    otherwise the list of help topics is printed.

    Options:
      -d    output short description for each topic
      -m    display usage in pseudo-manpage format
      -s    output only a short usage synopsis for each topic matching
        PATTERN

    Arguments:
      PATTERN   Pattern specifiying a help topic

    Exit Status:
    Returns success unless PATTERN is not found or an invalid option is given.

@mikeserv sed의 스크립트에서 영감을 받아 Perl을 사용하여 매뉴얼 페이지의 관련 부분을 인쇄하는 작은 함수가 있습니다. 쉘의 초기화 파일( ~/.bashrcbash의 경우)에 다음 행을 추가하십시오.

manperl(){ man "$1" | perl -00ne "print if /^\s*$2\b/"; }

그런 다음 매뉴얼 페이지와 섹션 이름을 지정하여 실행하십시오.

$ manperl bash while
       while list-1; do list-2; done
       until list-1; do list-2; done
              The while command continuously executes the list list-2 as long as the last command in the list list-1 returns an exit
              status of zero.  The until command is identical to the while command, except that the test is negated; list-2 is  exe‐
              cuted  as  long  as the last command in list-1 returns a non-zero exit status.  The exit status of the while and until
              commands is the exit status of the last command executed in list-2, or zero if none was executed.

$ manperl grep SYNOPSIS
SYNOPSIS
       grep [OPTIONS] PATTERN [FILE...]
       grep [OPTIONS] [-e PATTERN | -f FILE] [FILE...]

$ manperl rsync "-r"
       -r, --recursive
              This tells rsync to copy directories recursively.  See also --dirs (-d).

답변2

일부 쉘 내장 기능이 전체 매뉴얼에 거의 표시되지 않는 것은 사실이지만, 특히 bashGNU 시스템에서만 사용할 가능성이 있는 특정 내장 기능은 더욱 그렇습니다.(GNU 사람들은 일반적으로 이것을 믿지 않으며 man자신의 info페이지를 선호합니다)- 대부분의 POSIX 유틸리티(셸 내장 여부 또는 기타)는 POSIX 프로그래머 가이드에서 잘 다루고 있습니다.

이것은 내 바닥에서 발췌 한 것입니다.man sh (약 20페이지 정도...)

여기에 이미지 설명을 입력하세요.

그들 모두가 거기에 있고, 언급되지 않은 다른 사람들도 있습니다. 예를 들어 set... 음, 모두 이름을 지정할 필요는 없습니다. 하지만 오른쪽 하단에 POSIX Category 1 Manual Series라고 적혀 있습니다. 이것이 제가 말하는 페이지입니다.readbreak(1P)man

아마도 하나의 패키지만 설치하면 될까요?이것데비안 시스템은 유망해 보입니다. 유용 하지만 , 해당 시리즈를 찾을 수 있다면 help반드시 구입해야 합니다 . POSIX Programmer's Guide이는 매우 도움이 될 수 있습니다. 구성 페이지가 매우 상세합니다.

그 외에도 쉘 내장 기능은 거의 항상 해당 특정 쉘에 대한 매뉴얼의 특정 섹션에 나열되어 있습니다. zsh예를 들어 완전히 별도의 페이지가 있습니다 man.zsh( 총 8~9페이지 정도였던 것 같아요 . zshall엄청났어요.)

물론 당신은 할 수 grep man:

man bash 2>/dev/null | 
grep '^[[:blank:]]*read [^`]*[-[]' -A14

   read [-ers] [-a aname] [-d  delim]  [-i  text]  [-n
   nchars]  [-N  nchars]  [-p prompt] [-t timeout] [-u
   fd] [name ...]
          One line is read from the standard input, or
          from  the  file descriptor fd supplied as an
          argument to the -u  option,  and  the  first
          word is assigned to the first name, the sec‐
          ond word to the second name, and so on, with
          leftover words and their intervening separa‐
          tors assigned to the last  name.   If  there
          are  fewer  words read from the input stream
          than names, the remaining names are assigned
          empty  values.   The  characters  in IFS are
          used to split the line into words using  the
          same  rules  the  shell  uses  for expansion

...이것은 내가 쉘 페이지를 검색할 때 하던 것과 꽤 유사합니다 man. 그러나 대부분의 경우 help꽤 좋습니다.bash

나는 실제로 sed이런 종류의 일을 처리하기 위해 최근에 스크립트를 작성하고 있습니다. 위 사진의 부품을 이렇게 잡았습니다. 여전히 제가 원하는 것보다 더 길지만 점점 개선되고 있으며 매우 편리합니다. 현재 반복에서는 명령줄에 제공된 [a] 패턴을 기반으로 섹션 또는 하위 섹션 제목과 일치하는 텍스트의 상황에 맞는 부분을 매우 안정적으로 추출합니다. 출력에 색상을 지정하고 표준 출력으로 인쇄합니다.

들여쓰기 수준을 평가하여 작동합니다. 비어 있지 않은 입력 줄은 일반적으로 무시되지만, 빈 줄을 만나면 주의를 기울이기 시작합니다. 다른 빈 줄이 나타나기 전에 현재 시퀀스가 ​​실제로 첫 번째 줄보다 더 많이 들여쓰기되었는지 확인할 때까지 거기에서 줄을 수집합니다. 그렇지 않으면 스레드를 삭제하고 다음 공백을 기다립니다. 테스트가 성공하면 리드 라인을 명령줄 인수와 일치시키려고 시도합니다.

이것은 다음을 의미합니다성냥패턴은 다음과 일치합니다.

heading
    match ...
    ...
    ...
        text...

..그리고..

match
   text

..하지만..

heading
    match
    match

    notmatch

..또는..

         text

         match
         match
         text

         more text

일치할 수 있으면 인쇄가 시작됩니다. 인쇄하는 모든 줄에서 일치하는 줄의 선행 공백을 제거하므로 들여쓰기 수준에 관계없이 맨 위에 있는 것처럼 인쇄합니다. 일치하는 줄보다 들여쓰기 수준이 같거나 작은 다른 줄을 만날 때까지 인쇄를 계속합니다. 따라서 헤더 일치만 포함할 수 있는 모든 하위 섹션, 단락을 포함하여 전체 섹션을 가져옵니다.

따라서 기본적으로 특정 패턴과 일치하도록 요청하면 특정 주제 제목과만 일치하며 일치 시작 부분의 섹션에 있는 모든 텍스트에 색상을 지정하고 인쇄합니다. 첫 번째 줄의 들여쓰기 외에는 아무것도 저장하지 않습니다. 따라서 매우 빠르며 \n거의 모든 크기의 줄로 구분된 입력을 처리할 수 있습니다.

다음과 같은 자막으로 재귀하는 방법을 알아내는 데 시간이 걸렸습니다.

Section Heading
    Subsection Heading

그러나 나는 마침내 그것을 알아 냈습니다.

하지만 단순함을 위해 모든 것을 다시 디자인해야 했습니다. 이전에는 컨텍스트에 맞게 약간 다른 방식으로 거의 동일한 작업을 수행하는 여러 개의 작은 루프가 있었지만 재귀 방식을 변경하여 대부분의 코드 중복을 제거했습니다. 이제 두 개의 루프가 있습니다. 하나는 인쇄하고 다른 하나는 들여쓰기를 확인합니다. 둘 다 동일한 테스트에 의존합니다. 테스트가 통과하면 인쇄 루프가 시작되고, 테스트가 실패하거나 빈 줄에서 시작되면 들여쓰기 루프가 이어집니다.

대부분의 경우 /./d비어 있지 않은 행을 삭제하고 다음 행으로 이동하므로 전체 프로세스가 매우 빠릅니다. 심지어 결과도 zshall즉시 화면에 채워집니다. 이것은 변하지 않았습니다.

어쨌든 지금까지는 매우 유용했습니다. 예를 들어 read위의 작업은 다음과 같이 수행할 수 있습니다.

mansed bash read

...전체 블록을 얻었습니다. 어떤 패턴이든 무엇이든 사용할 수 있으며 여러 매개변수를 사용할 수 있지만 첫 번째 매개변수는 항상 man검색해야 하는 페이지입니다. 이것은 사진이다일부이 작업을 수행한 후의 출력은 다음과 같습니다.

mansed bash read printf

여기에 이미지 설명을 입력하세요.

...두 청크가 모두 그대로 반환됩니다. 나는 종종 다음과 같이 사용합니다.

mansed ksh '[Cc]ommand.*'

...매우 유용합니다. 또한 다음을 SYNOPS[ES]얻는 것이 매우 편리합니다.

여기에 이미지 설명을 입력하세요.

한 번 해보고 싶다면 이것이 전부입니다. 그렇지 않더라도 저는 당신을 비난하지 않을 것입니다.

mansed() {
MAN_KEEP_FORMATTING=1 man "$1" 2>/dev/null | ( shift
b='[:blank:]' s='[:space:]' bs=$(printf \\b) esc=$(printf '\033\[') n='\
' match=$(printf "\([${b}]*%s[${b}].*\)*" "$@")
sed -n "1p
    /\n/!{  /./{    \$p;d
        };x;    /.*\n/!g;s///;x
    :indent
        /.*\n\n/{s///;x
        };n;\$p;
        /^\([^${s}].*\)*$/{s/./ &/;h;   b indent
        };x;    s/.*\n[^-[]*\n.*//; /./!x;t
        s/[${s}]*$//;   s/\n[${b}]\{2,\}/${n} /;G;h
    };
    #test
    /^\([${b}]*\)\([^${b}].*\n\)\1\([${b}]\)/!b indent
        s//\1\2.\3/
    :print
    /^[${s}]*\n\./{ s///;s/\n\./${n}/
        /${bs}/{s/\n/ & /g;
            s/\(\(.\)${bs}\2\)\{1,\}/${esc}38;5;35m&${esc}0m/g
            s/\(_${bs}[^_]\)\{1,\}/${esc}38;5;75m&${esc}0m/g
            s/.${bs}//g;s/ \n /${n}/g
            s/\(\(${esc}\)0m\2[^m]*m[_ ]\{,2\}\)\{2\}/_/g
        };p;g;N;/\n$/!D
        s//./;  t print
    };
    #match
        s/\n.*/ /;  s/.${bs}//g
        s/^\(${match}\).*/${n}\1/
        /../{   s/^\([${s}]*\)\(.*\)/\1${n}/
        x;  s//${n}\1${n}. \2/; P
    };D
");}

간단히 말해서 작업 흐름은 다음과 같습니다.

  • 공백이 아니고 \n줄바꿈 문자를 포함하지 않는 줄은 출력에서 ​​제거됩니다.
    • \newline 문자는 입력 패턴 공간에 나타나지 않습니다. 편집의 결과로만 존재할 수 있습니다.
  • :print:indent다 상호 의존적인 폐쇄 루프이며 \newline을 얻는 유일한 방법입니다.
    • :print줄의 선행 문자가 일련의 공백이고 그 뒤에 줄 바꿈 문자가 있는 경우 \n루프 주기가 시작됩니다 .
    • :indent루프는 빈 줄(또는 :print실패한 루프 줄 )로 시작하지만 #test출력에서 :indent​​모든 선행 공백 + \n줄바꿈 시퀀스를 제거합니다.
    • 일단 :print시작되면 입력 줄을 계속해서 가져와서 루프의 첫 번째 줄에 있는 숫자로 선행 공백을 제거하고, thump 및 undertap 백스페이스 이스케이프를 컬러 터미널 이스케이프로 변환하고, #test실패할 때까지 결과를 인쇄합니다.
    • 시작하기 전에 :indent먼저 h들여쓰기된 연속이 가능한지 이전 공간을 확인합니다.(예: 섹션)그런 다음 #test실패할 때마다 입력을 계속 가져오면 첫 번째 줄 이후의 모든 줄이 계속 일치합니다 [-. 첫 번째 줄 이후의 줄이 패턴과 일치하지 않으면 삭제됩니다. 이후 모든 후속 줄은 다음 빈 줄까지 삭제됩니다.
  • #match#test두 개의 닫힌 루프를 연결합니다 .
    • #test선행 공백 시퀀스가 \n​​행 시퀀스의 마지막 줄 뒤의 공백 시퀀스보다 짧은 경우 통과합니다.
    • #match\n명령줄 인수와 일치하는 출력 시퀀스 :print에 루프를 시작하는 데 필요한 선행 줄을 추가합니다. :indent존재하지 않는 시퀀스는 빈 것으로 렌더링되고 결과로 생성된 빈 줄은 다시 전달됩니다 :indent.

답변3

각 쉘에는 자체 내장 기능 세트가 있습니다. 공통점이 있지만 모두 문서화해야 할 고유한 특성이 있습니다.

Linux 및 FreeBSD(및 FreeBSD의 후속 OSX)와 같은 시스템에서는 각 셸이 별도의 패키지로 제공되므로 내장 명령에 대한 매뉴얼 페이지가 없으며 대신 각 내장 기능이 셸의 맨 페이지 . 따라서 bash 내장 기능에 대한 문서는 bash 매뉴얼 페이지를 읽고 kill, dash 내장 기능에 대한 문서는 dash 매뉴얼 페이지를 읽어보세요 kill. kill독립 실행형 유틸리티에 대한 매뉴얼 페이지 도 있습니다 .

바라보다Bash 내장 명령에 대한 별도의 매뉴얼 페이지를 얻을 수 있습니까?man인수가 내장 함수의 이름인 경우 함수에 대한 매뉴얼 페이지 대신 bash 내부 문서가 표시됩니다.

일부 Unix 변형은 쉘 내장 명령에 대한 매뉴얼 페이지를 제공합니다. 실제로 대부분의 상용 변형은 그렇게 합니다. 이는 시스템이 단일 쉘 또는 알려진 쉘 세트와 함께 제공되기 때문에 가능합니다. 매뉴얼 페이지에서는 쉘 간의 차이점을 설명합니다. 예를 들어,fg(1)Solaris 10 매뉴얼 페이지sh, ksh및 부분이 있습니다 csh. 이것fg(1)AIX 7.1의 매뉴얼 페이지"Korn 쉘"과 "POSIX 쉘"을 참조하면서 함께 논의합니다(두 가지는 정확히 동일한 기능을 지원합니다 fg). 이것fg(1)Tru64 5.0 매뉴얼 페이지ksh 내장 기능에 대해 논의하고 csh 사용자에게 csh(1)매뉴얼 페이지를 참조합니다.상하이협력기구분명히 케이스가 함께 제공됩니다. 이러한 운영 체제에 추가 기능 패키지로 다른 쉘을 설치할 수 있습니다. 사용자 정의 쉘을 사용하는 경우 기본 쉘이 아닌 쉘을 사용할 때는 내장 기능에 대한 매뉴얼 페이지가 관련이 없다는 점을 기억해야 합니다.

관련 정보