함수 정의를 실행하고 함수를 호출할 때 다음 중 함수 본문 내에서 수행되는 셸 작업은 무엇입니까?

함수 정의를 실행하고 함수를 호출할 때 다음 중 함수 본문 내에서 수행되는 셸 작업은 무엇입니까?

기능 정의명령이다. 함수 정의가 실행되면 함수 본문이 작은따옴표인 것처럼 그대로 유지될 것이라고 생각합니다.

나는 다음을 배웠을 때 내가 틀렸다는 것을 알았습니다.배쉬 매뉴얼 존재하다G맨의 대답 나에게 주어진별칭 및 기능질문:

별칭은 함수가 실행될 때가 아니라 함수 정의를 읽을 때 확장됩니다.…

따라서 다음 예와 같이 별칭 확장은 함수 본문에서 수행되지만 매개변수 확장은 수행되지 않습니다.

$ alias myalias=cat
$ echo $var
3
$ myfunc() { myalias myfile; echo $var; }
$ declare -fp myfunc
myfunc () 
{ 
    cat myfile;
    echo $var
}

비슷하게,함수 호출명령이기도 합니다.

함수에 정의된 별칭은 함수가 실행된 후에만 사용할 수 있습니다.

따라서 별칭 정의는 함수 정의가 실행될 때가 아니라 실행 시(즉, 함수가 호출될 때)에만 실행됩니다.

별칭 확장 및 별칭 정의 실행은 아래 나열된 셸 작업 중 두 가지에 불과합니다.

내 질문은 다음과 같습니다

  1. 함수 본문 내에서 어떤 쉘 작업이 수행되고, 어떤 작업이 수행되지 않습니까?

    • 언제함수 정의 실행?

    • 언제통화 기능,즉,기능을 실행하다?

  2. 함수 정의 실행과 함수 호출 사이에 쉘 작업이 수행됩니까?

    아니면 함수 정의를 실행하고 해당 함수를 호출하면 겹치지 않는 쉘 작업 세트가 수행됩니까?

가능한 조치는 다음 인용문에 나열되어 있습니다.배쉬 매뉴얼:

3.1.1 쉘 동작

다음은 명령을 읽고 실행할 때 쉘의 작업에 대한 간략한 설명입니다. 기본적으로 쉘은 다음을 수행합니다.

  1. 읽다입력은 파일(39 페이지의 3.8절 [쉘 스크립팅] 참조), 호출 옵션에 대한 인수로 제공되는 문자열 -c(80 페이지의 6.1절 [Bash 호출] 참조) 또는 사용자 터미널에서 옵니다.

  2. 휴식 시간6페이지 3.1.2항 [참고]에 설명된 인용 규칙을 준수하면서 단어와 연산자를 입력합니다. 이러한 태그는 메타 문자로 구분됩니다.별칭 확장이 절차를 수행하십시오(88 페이지의 섹션 6.6 [별칭] 참조).

  3. 분석하다토큰을 단순 및 복합 명령으로 변환합니다(8 페이지의 섹션 3.2 [쉘 명령] 참조).

  4. 다양한 수행쉘 확장(21 페이지의 섹션 3.5 [쉘 확장] 참조) 확장 태그를 파일 이름 목록(30 페이지의 섹션 3.5.8 [파일 이름 확장자] 참조)과 명령 및 인수로 나눕니다.

  5. 필요한 조치를 수행하십시오.리디렉션(31페이지의 섹션 3.6 [리디렉션] 참조) 인수 목록에서 리디렉션 연산자와 해당 피연산자를 제거합니다.

  6. 구현하다(35페이지의 3.7절 [명령 실행하기] 참조)

  7. 선택 과목기다리다명령이 완료되고 종료 상태가 수집됩니다(38페이지의 섹션 3.7.5 [종료 상태] 참조).

답변1

<rant>
"실행 함수 정의"와 "실행 함수 정의"는 일반적인 관용어가 아닙니다. 나는 대부분의 사람들이 이것을 단순히 "함수 정의"라고 부를 것이라고 예상합니다. 좋아요, 이 문구는 다음을 가리키는 것으로 해석될 수 있습니다.

  1. 기능(개인 또는 그룹이 수행하는 활동)의 특성과 인터페이스(매개변수 및 기타 입력, 처리 및 출력)를 개념적으로 지정합니다.
  2. 함수 구현, 즉 함수 본문에서 사용할 명령을 선택합니다. 이는 종이, 화이트보드 및/또는 칠판을 사용하여 한 사람 또는 여러 사람이 수행할 수 있는 활동입니다.
  3. 유형기능을 텍스트 편집기나 직접 대화형 셸에 구현합니다(물론 이는반품개인 또는 여러 사람이 수행하는 활동 또는 매우 지능적이고 민첩한 고양이, 개 또는 원숭이가 수행하는 활동)

위와 혼동될까봐 걱정된다면 "함수 정의 읽기", "함수 정의 처리"와 같은 문구가 더 나을 수도 있습니다.

"함수 정의는 명령이다"라고 말씀하셨는데, 이것이 무엇을 의미하는지 명확하지 않습니다. 의미론의 문제이지만 의미론적 수준에서는 논쟁의 여지가 있습니다.  Bash 매뉴얼 섹션 3.2(셸 명령) 6개의 셸 명령(단순 명령, 파이프, 목록, 복합 명령, coprocess 및 GNU 병렬)이 나열됩니다. 함수 정의는 이러한 범주에 잘 맞지 않습니다.
</rant>

귀하의 질문에 답하려면 7가지 단계/조치를 살펴보세요.

  1. 입력 읽기는 분명히 이전에 이루어져야 합니다.아무것그렇지 않으면 이런 일이 발생할 수 있습니다. 이것은 다시 의미론의 문제입니다. 파일이나 다른 스트리밍 텍스트 소스에서 입력을 읽는 것이 "함수 정의 읽기"의 일부이거나 "함수 정의 처리"의 전제 조건/전주곡이라고 말할 수 있습니다.
  2. 입력을 단어와 연산자로 나누는 것은 분명히 "함수 정의 처리"의 일부입니다.
    • 물론 입력을 토큰으로 분해하는 것은 전제 조건/전주곡입니다.분석하다토큰(아래 3단계).
    • 매뉴얼에는 "이 단계를 통해 별칭 확장이 수행됩니다"라고 나와 있으며, 함수 정의를 읽을 때 별칭 확장이 발생한다는 것을 알고 있다고 질문에 표시했습니다.
  3. 마크업을 구문 분석합니다. 이 작업은 최소한 "프로세스 기능 정의" 단계에서 시작되어야 합니다.깨닫다단순한 명령보다는 기능 정의를 살펴보는 것입니다. 그렇지 않으면 다음과 같은 간단한 실험을 수행할 수 있습니다. 다음 중 하나를 셸에 입력합니다.

    myfunc1() {                     myfunc2() {
        <               or              ;
    }                               }
    

    ( }그리고 동일한 효과를 >생성합니다 .) 분명히 이 단계는 함수 정의를 처리하는 과정의 일부입니다.&


  1. 호출 기능의 일부로 다양한 셸 확장이 수행됩니다.
    • 질문에 매개변수 확장에 대해 알고 있다고 표시하셨습니다.확실히발생하다 함수 정의를 읽을 때.
    • 함수 정의를 읽을 때 경로명/파일명 확장이 발생하지 않는다는 것을 증명하는 것도 마찬가지로 간단합니다. 귀하의 예에서는 echo $var (이어야 echo "$var"하지만 다른 이야기입니다)를 로 변경하십시오 echo *.
      • 함수 정의를 보면 여전히 표시되고 echo *확장되지 않은 것을 볼 수 있습니다.
      • 디렉터리 변경( cd) 및/또는 파일 생성 및/또는 파일 삭제 및/또는 파일 이름 변경 후 함수를 호출(실행)합니다. 출력되는 것을 볼 수 있습니다현재의현재 디렉터리에 있는 파일 1 의 목록 이며 함수가 정의된 시점의 디렉터리 내용을 반영하지 않습니다.
  2. 리디렉션을 수행하는 것은 이 함수 호출의 일부입니다. 이것도 확인하기 쉽습니다. 귀하의 예에서는 echo $var로 변경하십시오 echo hello > myfile.
    • 함수 정의를 보면 여전히 로 나타나는 것을 볼 수 있습니다  > myfile.
    • 디렉토리를 확인하면 myfile아직 생성되지 않았음을 알 수 있습니다.
  3. 명령 실행 – 꼭 물어볼 필요가 있었나요?
  4. 명령을 실행하기 전에 명령이 완료될 때까지 기다릴 수 없으므로(6단계) 함수가 호출될 때만 이 작업을 수행합니다.

다시 말해서,@ilkkachu님 말씀대로.

제가 생각할 수 있는 특별한 경우 예외 중 하나는 함수에 eval명령문이 포함된 경우 함수가 실행될 때 2단계와 3단계(어휘 분석 및 구문 분석)가 (다시) 발생한다는 것입니다. 그러나 이는 귀하의 질문이 실제로 요구하는 범위를 넘어서는 것이라고 생각합니다.
____________ 1지정하지 않는 한 숨겨진(점) 파일을 포함하지 않습니다
.shopt -s dotglob

관련 정보