쉘 내장, 함수, 파이프 및 명령 목록의 예약어와 "time" 명령의 차이점은 무엇입니까?

쉘 내장, 함수, 파이프 및 명령 목록의 예약어와 "time" 명령의 차이점은 무엇입니까?

Bash 참조 매뉴얼에서,

time타이밍을 허용하기 위해 예약어로 사용쉘 내장 함수,쉘 기능, 그리고관로. 외부 명령 time으로는 쉽게 시간을 측정할 수 없습니다 .

  1. 인용문에서 왜 이런 말을 하는지 설명해 주실 수 있나요?

    이는 단지 의 경우가 아닌 예약어와 명령어의 차이 때문인가요 time? 예를 들어, bash 쉘은 이를 어떻게 다르게 구문 분석하거나 해석합니까?

    아니면 다음과 같은 경우에만 해당되나요 time?

  2. 다음 예에서는

    time"쉽게 시간을 측정할 수 없다"는 인용문이 있는데, 내장된 쉘과 파이프에서 외부 작업이 수행되는 이유는 무엇입니까 ?

    외부 time개구내장 쉘:

    $ /usr/bin/time echo hello
    hello
    0.00user 0.00system 0:00.00elapsed 0%CPU (0avgtext+0avgdata 1676maxresident)k
    0inputs+0outputs (0major+78minor)pagefaults 0swaps
    

    외부 time개구파이프라인:

    $ /usr/bin/time sleep 10 | sleep 5
    0.00user 0.00system 0:10.00elapsed 0%CPU (0avgtext+0avgdata 1776maxresident)k
    0inputs+0outputs (0major+79minor)pagefaults 0swaps
    
  3. 아래 예에서 외부 time가 켜져 있는 이유는 무엇입니까?쉘 함수실패하다? 오류 출력은 무엇을 의미합니까?

    $ function mytest () { sleep 10; }
    
    $ /usr/bin/time mytest
    /usr/bin/time: cannot run mytest: No such file or directory
    Command exited with non-zero status 127
    0.00user 0.00system 0:00.03elapsed 0%CPU (0avgtext+0avgdata 1252maxresident)k
    32inputs+0outputs (0major+30minor)pagefaults 0swaps
    
  4. 이 문장은 타이밍 쉘 내장, 쉘 함수, 파이프에만 적용되는 것은 아닌 것 같습니다.타이밍에도 주의하세요일련의 명령:

    $ time { echo hello; sleep 3; echo tim; }
    hello
    tim
    
    real    0m3.002s
    user    0m0.000s
    sys 0m0.000s
    
    
    $ /usr/bin/time { echo hello; sleep 3; echo tim; }
    bash: syntax error near unexpected token `}'
    

    }명령의 경우 쉘에 "bash: 예상치 못한 토큰 근처의 구문 오류"가 표시되는 이유는 무엇 입니까 /usr/bin/time?

답변1

에서 bashtime하나입니다예약어, 따라서 쉘은 이를 자체 방식으로 구문 분석하고 규칙을 적용할 수 있습니다.

예약어로 시작하는 줄을 구문 bash분석하는 방법을 보여주는 코드는 다음과 같습니다.time:

static int
time_command_acceptable ()
{
#if defined (COMMAND_TIMING)
  int i;

  if (posixly_correct && shell_compatibility_level > 41)
    {
      /* Quick check of the rest of the line to find the next token.  If it
     begins with a `-', Posix says to not return `time' as the token.
     This was interp 267. */
      i = shell_input_line_index;
      while (i < shell_input_line_len && (shell_input_line[i] == ' ' || shell_input_line[i] == '\t'))
        i++;
      if (shell_input_line[i] == '-')
    return 0;
    }

  switch (last_read_token)
    {
    case 0:
    case ';':
    case '\n':
    case AND_AND:
    case OR_OR:
    case '&':
    case WHILE:
    case DO:
    case UNTIL:
    case IF:
    case THEN:
    case ELIF:
    case ELSE:
    case '{':       /* } */
    case '(':       /* )( */
    case ')':       /* only valid in case statement */
    case BANG:      /* ! time pipeline */
    case TIME:      /* time time pipeline */
    case TIMEOPT:   /* time -p time pipeline */
    case TIMEIGN:   /* time -p -- ... */
      return 1;
    default:
      return 0;
    }
#else
  return 0;
#endif /* COMMAND_TIMING */
}

알다시피, time그 뒤에는 대부분의 다른 bash예약어가 올 수 있습니다.

외부 명령인 경우 일반 규칙이 적용되고 {입력으로 처리됩니다 /usr/bin/time. }단독으로는 유효하지 않은 토큰이며 bash오류가 발생합니다.


존재하다:

/usr/bin/time echo hello

external은 time쉘 내장 명령을 호출하지 않고 echo외부 echo명령을 호출합니다.

확인 strace:

$ strace -fe execve /usr/bin/time echo 1
execve("/usr/bin/time", ["/usr/bin/time", "echo", "1"], [/* 64 vars */]) = 0
Process 25161 attached
....
[pid 25161] execve("/usr/bin/echo", ["echo", "1"], [/* 64 vars */]) = -1 ENOENT (No such file or directory)
[pid 25161] execve("/bin/echo", ["echo", "1"], [/* 64 vars */]) = 0
1
[pid 25161] +++ exited with 0 +++
....

실행 가능한 명령을 찾으려면 여기 외부에서 time변수 를 찾아보세요. PATH이는 또한 기능을 사용하는 경우 다음을 얻는다는 것을 설명합니다.해당 파일이나 디렉터리가 없습니다.mytest당신 때문에 PATH.

답변2

/usr/bin/time2.에서는 특히 파이프의 첫 번째 명령(10초)을 곱하는 두 번째 경우에 출력이 잘못되었음을 알 수 있습니다 . 그런 다음 명령 출력 은 명령줄을 다음과 같은 방식으로 구분하는 셸로 /usr/bin/time sleep 10파이프 됩니다. 이는 다른 명령과 같습니다.sleep 5/usr/bin/time

3. 쉘 함수는 쉘 프로세스 내부에 있습니다. /usr/bin/time인수를 사용하여 호출하면 mytest명령 경로를 검색하지만 아무것도 찾지 못합니다. /usr/bin/time쉘에 의해 호출되지만 쉘의 일부는 아닙니다.

관련 정보