이 목적을 위해 Bash 함수를 다른 함수(예: 중첩)와 함께 선언/내보내는 것이 가능합니까?

이 목적을 위해 Bash 함수를 다른 함수(예: 중첩)와 함께 선언/내보내는 것이 가능합니까?

예를 들어, 다소 다루기 어려워진 스크립트에서 IDE의 매우 유용한 트리/개요 기능 중 일부를 활용하려면 항목을 중첩하여 축소 가능한 트리가 되어야 합니다.

스크립트 개요 보기의 축소된 함수

내가 이해한 바로는(저는 아직 초보자입니다) 함수는 동일한 셸에서 실행됩니다. 즉, 하위 셸이 아닙니다. 따라서 이를 염두에 두고 큰 함수 그룹을 그룹화하여 앞에 넣을 수 있다고 생각했습니다 set -a. 예를 들어, 다른 함수로 래핑되었습니다.

functiongroup() {        # ← moved from this level ─╮
  set -a                 #                         ╭╯
  func1() { …;}          #   ← grouped functions ──┤
  func2() { …;}          #   ← grouped functions ──╯
  …                      #
}                        #
…                        #
functiongroup            # ← invoke functions function

...또는 올바르게 선언하면 됩니다 declare.

이로 인해 문제가 발생합니까?

그렇지 않다고 가정하면 그들은 그럴 것입니다.새로운 부모 함수- 스크립트의 특정 위치를 공격할 것임을 알 수 있도록 호출해야 합니까? 다시 말하면 다음과 같습니다.Bash는 상위 함수를 실행하기 전에 중첩된 함수를 처리(알고)합니까?

코드가 다음과 같다고 가정해 보겠습니다.

  1 │ #!/usr/bin/env bash
  2 │ # FUNCTIONS & VARS
  3 │ functiongroup() {                # ← moved from this level ─╮
  4 │   set -a                         #                         ╭╯
  5 │   func1() { …;}                  #   ← grouped functions ──┤
  6 │   func2() { …;}                  #   ← grouped functions ──╯
  7 │   …                              #
  8 │ }                                #
  9 │ # PROGRAM                        #
 10 │                                  # ← moved to line 12
 11 │ echo -n "something $(func2)"     # ← func2 call
 12 │ functiongroup                    # ← accidentally moved a line too late
 13 │ if func1; then                   # ← func1 call                  
 14 │   do                             #         
 15 │     …                            #         
 16 │   done                           #           
 17 │ else                             #       
 18 │   echo "MELTDOWN!"               #           
 19 │   exit 1                         #           
 20 │ fi                               #           
 21 │ exit 0                           #           

위에서 func1실행 됩니까 func2, 아니면 그냥 실행됩니까 func1? (그렇다면)

내 참조는 GNU입니다배쉬 매뉴얼때로는 너무 촘촘할 수 있으므로 이것과 비교했습니다.컨닝 지StackExchange 아이디어를 많이 찾았지만, 완전히 이해하지 못하면 코드를 사용하지 않을 것이기 때문에 원하는 만큼 빨리 학습되지는 않습니다. 확실히 선형적이지는 않습니다. :(

나는 이것이 간단하고 최종 스크립트가 무엇을 하는지 언제든지 알 수 있기 때문에 이것을 좋아합니다. 그러나 그것을 구성하는 적절하고 더 나은 방법이 있다면 알려 주시기 바랍니다.

감사해요.


*: 나중에 필요한 지식 수준에 도달했을 때 검토할 수 있도록 코드 조각을 노트에 보관하지만 기억할 수 있는 한. Bash, PHP, Python, JavaScript, PowerShell, 심지어 HTML까지... 검열되지 않은 코드의 백로그가 있습니다.

답변1

Bash는 상위 함수를 실행하기 전에 중첩된 함수를 처리(알고)합니까?

아니요.

한번 시도해 봅시다:

$ funcgroup() {
    f1() { echo this is f1; }
    f2() { echo this is f2; }
}

$ f2
f2: command not found

$ funcgroup

$ f2
this is f2

스크립트를 사용하기 어려워지면 함수를 라이브러리로 분리하세요.

$ bash

$ cat funcs.bash
f1() { echo this is f1; }
f2() { echo this is f2; }

$ f2
f2: command not found

$ . funcs.bash

$ f2
this is f2

.(일명) 명령은 source현재 디렉터리와 PATH에서 파일을 찾습니다.

답변2

첫 번째 답변에서 알 수 있듯이 일반적으로 프로그램을 별도의 모듈로 정렬하는 것이 좋습니다. 특히 너무 많은 공간을 차지하는 비대한 소프트웨어는 더욱 그렇습니다.

그러나 문제는 스크립트를 호출하는 방법에 주의해야 한다는 것입니다. 경로가 변경되고 초기 스크립트가 결국 라이브러리를 찾지 못할 수 있기 때문에 라이브러리를 가져오는 초기 스크립트를 호출하는 위치와 다릅니다.

나는 일반적으로 이 문제를 회피하기 위해 다음 기능을 사용합니다.

function whereAmI { printf "$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"; }

이는 이 프로세스를 실행하는 스크립트가 어디에 있는지 알려줍니다.

따라서 라이브러리가 초기 스크립트와 관련된 어딘가에 있으면 항상 라이브러리를 찾습니다. 예를 들어 해당 상대 경로에 lib/결과를 추가하는 경우입니다 .whereAmI

그럼에도 불구하고 언어의 한계로 인해 Bash 코드를 잘 구성하는 것이 중요합니다. 그렇지 않으면 지금부터 1년 후에 보면 모든 것이 말이 되지 않습니다.

관련 정보