함수 정의만 포함하는 스크립트를 작성하시겠습니까? 아니면 함수 본문의 코드를 스크립트로 이동하시겠습니까?

함수 정의만 포함하는 스크립트를 작성하시겠습니까? 아니면 함수 본문의 코드를 스크립트로 이동하시겠습니까?

일부 배경:Bash에서 재사용 가능한 코드를 작성할 때 나는 몇 가지를 보았습니다. 여러 함수 정의가 포함된 쉘 스크립트. 때로는 스크립트에 정의된 함수가 관련되어 있는지, 스크립트가 실제로 엉망인지, 또는 여러 함수를 하나의 스크립트로 구성하는 방법을 알 수 없는지 알 수 없습니다(이 목적에 대한 제안 사항이 있습니까?) . 그래서 하나의 함수 정의만 포함하는 스크립트를 작성할 생각인데 여러 파일을 정리해야 할 것 같습니다. 하나의 스크립트에 여러 함수 정의를 구성하는 것과 각각 함수 정의가 포함된 여러 스크립트 파일을 구성하는 것 중 어느 것이 더 낫습니까?

다음에서는 하나의 함수 정의만 포함하는 스크립트를 작성한다고 가정하겠습니다.


내 실제 질문여기에서 시작하세요:

글을 쓰는 동안하나의 함수 정의만 포함하는 스크립트,난 쓸수있다

#! /bin/bash

function myfunc() {
    echo $1, $2, $3
    # do some work...
}

그럼 내가 써도 돼

source /path/to/myscript
myfunc 1 2 3

또는 함수 정의를 제거하고 함수 본문의 코드를 스크립트로 이동하여 동일한 코드 재사용성 목표를 달성할 수 있습니다.

#! /bin/bash

echo $1, $2, $3
# do some work...

그럼 내가 써도 돼

source /path/to/myscript 1 2 3

? 두 번째 방법은 스크립트 내용이나 사용법 측면에서 첫 번째 방법보다 깔끔해 보이지만 어떤 이유로 두 번째 방법을 싫어할 사람이 있을지 모르겠습니다. 위의 두 가지 방법의 장점과 단점이 무엇인지 알고 싶습니다. 실제로 어떤 조언을 해주시나요?

실제로 첫 번째 접근 방식을 사용하는 경우 스크립트 이름을 함수와 동일하게 지정하시겠습니까? 즉, 스크립트에 이라는 함수가 포함된 경우 myfunc스크립트 이름도 로 지정하시겠습니까 myfunc?

감사해요.

답변1

저는 상황에 따라 둘 다 합니다. 대부분의 경우 이러한 함수를 사용할 동일한 스크립트에서 선언하지만 모든 스크립트 간에 공유하려는 변수 및 함수 파일이 포함된 스크립트 "키트"가 있습니다.

기능을 하든 안 하든

함수의 주요 목적은 DRY(반복하지 않음)입니다. 스크립트에서 여러 번 사용될 코드가 있는 경우 함수에 있어야 합니다.

반복되지 않는 코드에서 함수를 사용하는 것은 선호의 문제입니다. 어떤 사람들(나 자신 포함)은 그것이 더 깔끔하다고 생각합니다. 또한 "실제" 프로그래밍 언어가 사용되는 방식과 더 유사하다고 생각합니다.

구글의쉘 스타일 가이드코드에 함수가 하나 이상 포함된 경우 "main" 함수를 모든 코드 주위의 래퍼로 사용해야 한다는 점을 지적하세요. (본질적으로 스크립트는 단일 호출로 끝나는 일련의 함수 선언입니다 main.)

단일 스크립트 내에서 함수 선언(또는 코드 작성)

  • 단순함(코드를 보는 사람은 누구나 각 함수의 기능을 더 쉽게 추적할 수 있음)
  • 이식성 향상(한 시스템에서 다른 시스템으로 하나의 파일만 이동)

단일 작업을 수행하기 위해 독립형 스크립트를 작성하는 경우 이것이 올바른 선택일 수 있습니다.

별도의 파일에 함수 선언

  • DRY(반복하지 마세요)
  • 관리가 더 쉬울 수 있어요

많은 공통 기능을 공유하는 도구 세트를 만드는 경우 이것이 올바른 선택일 수 있습니다.

내 예에는 툴킷의 스크립트 전부 또는 적어도 대부분에서 사용되는 기능이 있습니다. 여기에는 재고 관리 시스템을 쿼리하고 서버에 대한 정보(예: IP 주소, 운영 체제 버전 등)를 반환하는 기능이 포함됩니다. 이 정보는 많은 도구에 유용하므로 모든 파일이 아닌 하나의 파일에서 이러한 함수를 선언하는 것이 합리적입니다. 별도의 파일. 또한 최근 재고 관리 시스템을 변경하여 10개 이상의 다른 파일을 변경하는 대신 새 시스템에 쿼리하기 위해 공통 파일만 변경하면 되고 다른 파일은 수정 없이 작동했습니다.

이것의 몇 가지 단점은 더 복잡하다는 것입니다. 각 파일에는 이 공통 파일을 가져오기 위한 다음 명령문이 있습니다.

if [[ -f "${0%/*}/lib/common.sh" ]]; then
    . "${0%/*}/lib/common.sh"
else
    echo "Error! lib/common.sh not found!"
    exit 1
fi

사용자가 도구 키트를 가져와 디렉터리 구조를 수정하거나 전체 디렉터리 구조를 가져오지 못하는 경우 공용 파일을 가져올 수 없기 때문에 도구가 예상대로 작동하지 않습니다.

답변2

이것은 예 또는 아니오 유형의 답변이 아닌 긴 답변이 될 것입니다. 이는 작업 과정을 선택할 때 고려해야 하는 Bash 기능이 다루는 다양한 프로그래밍 측면을 설명합니다.

마지막으로, 별도의 매개변수화된 소스 파일에서 단일 함수 정의의 데모를 찾을 수 있습니다.


기능은 다음과 같습니다:

  • 명명 된
  • 막힌코딩됨
  • 이것은 될 수있다재사용(여러번 호출됨)

위 사항을 고려할 때 어떤 이점이 있으며 대안이 있습니까?

  1. 논리적정리하다코딩됨

    특정 목적을 수행하는 명령 배치를 함께 그룹화하는 것은 매우 의미가 있습니다. 결국 그것은 단어의 의미 중 하나입니다.기능-뭔가 이런 저런 기능이 있네. 그러나 동일한 목표를 다른 방법으로도 달성할 수 있습니다.

    • 명령은 직관적으로 그룹화될 수 있습니다. 연속된 라인을 차지하고 빈 라인과 주석으로 코드의 나머지 부분과 분리됩니다. 아니면 같은 줄에 넣고 끝에 주석을 추가하세요.
    • 별도의 파일로 그룹화할 수 있습니다.처형된또는원천.
    • 중괄호를 사용하여 차단할 수 있습니다 { ... }.
    • 그룹화하여 개별적으로 실행할 수도 있습니다.서브쉘, 서브쉘 괄호 안에 배치된 경우 ( ... ). 1
  2. 일괄 작업

    함수에는 표준 Bash 연산자를 사용하여 쉽게 대량 I/O 리디렉션이 가능하다는 장점이 있습니다. 블록, 서브셸, 스크립트 실행 및 소스도 괜찮지만 순수한 시각적 명령 그룹의 경우 I/O 파일 설명자 변경은 exec.

  3. 현지화

    이는 단순 블록에 비해 함수의 특별한 점 중 하나입니다. 변수를 생성하는 기능 local. 이는 변수 가시성을 최소한으로 유지하여 더 넓은 네임스페이스의 혼란을 줄이고 격리를 도입하므로 일반적으로 좋은 프로그래밍 방식입니다. 이는 결국 귀중한 보안 기능입니다.

    여기에서 개별 스크립트와 하위 쉘을 선택할 수 있습니다. 위치 매개변수에 관해서는 소스 파일에도 동일하게 적용됩니다.

  4. 매개변수화하다

    각 함수에는 고유한 위치 매개변수 세트 등이 있습니다 $1. $2이를 통해 명령 호출 내에서 함수의 동작을 명시적으로 수정할 수 있습니다.

    여기서 대안으로는 독립형 스크립트와 소스 파일이 있습니다.

  5. 암호식별하다

    함수이름이는 명시적인 인식뿐만 아니라 실행 능력도 의미합니다. 그리고 여러 번 필요했습니다. 블록, 서브쉘, 일반 텍스트 그룹화 모두 {}루프로 둘러싸여 있지 않는 한 이 기능을 제공하지 않습니다. 스크립트와 소스 파일은 괜찮지만.

  6. 정보

    마지막으로, 함수 이름과 함수에 포함될 수 있는 주석은 코드의 이해도에 영향을 미칩니다. 다른 모든 옵션에 대한 여지는 있지만 서브셸 및 {}블록과 같은 익명 솔루션은 코드 블록에 대한 공식적인 제목(및 주소)을 제공할 수 없습니다.


다음 예에서는 단일 함수를 별도의 소스 파일에 적절하게 배치하는 방법을 보여줍니다.

case "$1" in
    a)
        f () { echo "This function was defined in a)."; }
        ;;
    b)
        f () { echo "This function was defined in b)."; }
        ;;
    *)
        f () { echo "This function was defined with no recognised argument."; }
        ;;
esac

이 조건부 정의는 함수 팩토리와 같습니다. 다른 곳에서 얻은 파일은 f해당 위치에 기능을 설치합니다. 이 모든 코드는 다른 함수에 포함될 수 있으며 현재로서는 별 차이가 없습니다. 그러나 함수 발생기가 그 자체로 하나의 개체가 될 만큼 충분히 커지면 이 접근 방식은 함수와 소스 파일이라는 두 가지 장점을 결합합니다.


당신은 또한 볼 수 있습니다

실제로 Bash는 유사한 함수 정의를 허용합니다. 이렇게 f () ( ...;)정의하면 f함수는 자체 하위 쉘에서 실행됩니다.

관련 정보