전체 bash 스크립트를 함수로 작성하는 이유는 무엇입니까?

전체 bash 스크립트를 함수로 작성하는 이유는 무엇입니까?

직장에서는 bash 스크립트를 자주 작성합니다. 내 상사는 다음 예와 유사하게 전체 스크립트를 기능으로 나눌 것을 제안했습니다.

#!/bin/bash

# Configure variables
declare_variables() {
    noun=geese
    count=three
}

# Announce something
i_am_foo() {
    echo "I am foo"
    sleep 0.5
    echo "hear me roar!"
}

# Tell a joke
walk_into_bar() {
    echo "So these ${count} ${noun} walk into a bar..."
}

# Emulate a pendulum clock for a bit
do_baz() {
    for i in {1..6}; do
        expr $i % 2 >/dev/null && echo "tick" || echo "tock"
        sleep 1
    done
}

# Establish run order
main() {
    declare_variables
    i_am_foo
    walk_into_bar
    do_baz
}

main

"가독성" 외에 이 작업을 수행할 이유가 있습니까? 몇 가지 추가 설명과 줄 간격을 추가하면 똑같이 잘 확립될 수 있다고 생각합니까?

스크립트를 더 효율적으로 실행하게 합니까(실제로는 그 반대일 것으로 예상합니다), 아니면 앞서 언급한 가독성 이상으로 코드를 수정하기 더 쉽게 합니까? 아니면 단지 스타일적 선호에 불과한 걸까요?

스크립트가 잘 보여주지는 않지만 실제 스크립트에 있는 함수의 "실행 순서"는 매우 선형적인 경향이 있습니다. 수행된 walk_into_bar작업에 따라 달라지며 다음 에 의해 설정된 작업에 따라 작동합니다. 실행 순서를 임의로 바꾸는 것은 우리가 일반적으로 수행하는 작업이 아닙니다. 예를 들어, 갑자기 뒤에 붙이고 싶지 않을 것입니다 . 그러면 문제가 발생할 수 있습니다.i_am_foodo_bazwalk_into_bardeclare_variableswalk_into_bar

위 스크립트를 작성하는 방법의 예는 다음과 같습니다.

#!/bin/bash

# Configure variables
noun=geese
count=three

# Announce something
echo "I am foo"
sleep 0.5
echo "hear me roar!"

# Tell a joke
echo "So these ${count} ${noun} walk into a bar..."

# Emulate a pendulum clock for a bit
for i in {1..6}; do
    expr $i % 2 >/dev/null && echo "tick" || echo "tock"
    sleep 1
done

답변1

가독성한 가지입니다. 그러나 더 많은 것이 있습니다모듈화이것보다. (반모듈화아마도 기능에 더 정확할 것입니다.)

함수에서는 일부 변수를 로컬로 유지할 수 있습니다.신뢰할 수 있음, 일이 엉망이 될 가능성을 줄입니다.

기능의 또 다른 장점은 다음과 같습니다.재사용 성. 함수가 코딩되면 스크립트에서 여러 번 적용할 수 있습니다. 다른 스크립트로 포팅할 수도 있습니다.

귀하의 코드는 지금은 선형적일 수 있지만 미래에는멀티스레딩, 또는다중 처리배쉬 세계에서. 일단 기능을 수행하는 방법을 배우면 평행 단계로 나아갈 수 있는 준비가 잘 갖추어진 것입니다.

추가할 점을 하나 더 추가합니다. Etsitpab Nioliv가 아래 설명에서 알 수 있듯이 일관된 엔터티로서의 기능에서 쉽게 리디렉션할 수 있습니다. 그러나 기능을 사용한 리디렉션에는 한 가지 측면이 더 있습니다. 즉, 리디렉션은 함수 정의에 따라 설정될 수 있습니다. 예:

f () { echo something; } > log

이제 함수 호출에 명시적인 리디렉션이 필요하지 않습니다.

$ f

이렇게 하면 많은 반복을 줄일 수 있으며, 이는 다시 신뢰성을 높이고 일을 순서대로 유지하는 데 도움이 됩니다.

또한보십시오

답변2

나는 책을 읽은 후 이와 동일한 스타일의 bash 프로그래밍을 사용하기 시작했습니다.Kfir Lavi의 블로그 게시물 "방어적 Bash 프로그래밍". 그는 몇 가지 타당한 이유를 제시했지만 개인적으로 저는 다음이 가장 중요하다고 생각합니다.

  • 절차가 설명적이 됩니다. 코드의 특정 부분이 수행해야 하는 작업을 파악하는 것이 훨씬 쉬워집니다. 코드 벽 대신 "아, find_log_errors함수가 해당 로그 파일에서 오류를 읽습니다"라는 메시지가 표시됩니다. 신을 사용하는 많은 awk/grep/sed 행을 찾는 것과 비교하면 긴 스크립트 중간에 어떤 유형의 정규식을 알고 있는지 알 수 있습니다. 주석이 없으면 거기에서 무엇을 하는지 알 수 없습니다.

  • set -x및 로 묶어 함수를 디버깅할 수 있습니다 set +x. 나머지 코드가 제대로 작동한다는 것을 알게 되면 이 트릭을 사용하여 해당 특정 기능만 디버깅하는 데 집중할 수 있습니다. 물론, 스크립트의 일부를 포함할 수 있지만, 긴 부분이라면 어떻게 될까요? 다음과 같이 하는 것이 더 쉽습니다.

       set -x
       parse_process_list
       set +x
    
  • 를 사용한 인쇄 사용법 cat <<- EOF . . . EOF. 나는 내 코드를 훨씬 더 전문적으로 만들기 위해 이 방법을 여러 번 사용해 왔습니다. 또, 기능 parse_args()부착 getopts이 꽤 편리합니다. 다시 말하지만, 이는 모든 것을 거대한 텍스트 벽으로 스크립트에 밀어넣는 대신 가독성에 도움이 됩니다. 이것을 재사용하는 것도 편리합니다.

그리고 분명히 이것은 C, Java 또는 Vala를 알고 있지만 bash 경험이 제한적인 사람에게는 훨씬 더 읽기 쉽습니다. 효율성에 관한 한, 할 수 있는 일이 많지 않습니다. bash 자체는 가장 효율적인 언어가 아니며 사람들은 속도와 효율성 측면에서 Perl과 Python을 선호합니다. 그러나 다음과 같은 nice기능을 수행할 수 있습니다.

nice -10 resource_hungry_function

각 코드 줄마다 nice를 호출하는 것과 비교할 때 이는 전체 입력 횟수를 줄이고 스크립트의 일부만 낮은 우선 순위로 실행하려는 경우 편리하게 사용할 수 있습니다.

제 생각에는 백그라운드에서 함수를 실행하는 것은 전체 명령문을 백그라운드에서 실행하려는 경우에도 도움이 됩니다.

이 스타일을 사용한 몇 가지 예는 다음과 같습니다.

답변3

내 의견에서는 함수의 세 가지 장점을 언급했습니다.

  1. 정확성을 테스트하고 확인하는 것이 더 쉽습니다.

  2. 함수는 향후 스크립트에서 쉽게 재사용(소스 제공)될 수 있습니다.

  3. 당신의 상사가 그들을 좋아합니다.

그리고 숫자 3의 중요성을 결코 과소평가하지 마십시오.

한 가지 문제를 더 해결하고 싶습니다.

... 따라서 실행 순서를 임의로 바꾸는 것은 우리가 일반적으로 수행하는 작업이 아닙니다. 예를 들어, 갑자기 declare_variables뒤에 붙이고 싶지 않을 것입니다 walk_into_bar. 그러면 문제가 발생할 수 있습니다.

코드를 함수로 나누는 것의 이점을 얻으려면 함수를 가능한 한 독립적으로 만들어야 합니다. 다른 곳에서 사용되지 않는 변수가 필요한 경우 walk_into_bar해당 변수를 에서 정의하고 로컬로 만들어야 합니다 walk_into_bar. 코드를 함수로 분리하고 상호 의존성을 최소화하는 과정은 코드를 더 명확하고 단순하게 만들어야 합니다.

이상적으로는 함수를 개별적으로 테스트하기 쉬워야 합니다. 상호 작용으로 인해 테스트하기가 쉽지 않다면 이는 리팩토링을 통해 이점을 얻을 수 있다는 신호입니다.

답변4

C/C++, Python, Perl, Ruby 또는 기타 프로그래밍 언어 코드에 대해 수행하는 것과 동일한 이유로 코드를 함수로 분할합니다. 더 깊은 이유는 추상화입니다. 낮은 수준의 작업을 더 높은 수준의 기본 요소(함수)로 캡슐화하므로 작업 수행 방법에 대해 걱정할 필요가 없습니다. 동시에, 코드는 더 읽기 쉽고 유지 관리하기 쉬워지고 프로그램 논리는 더 명확해집니다.

그러나 귀하의 코드를 살펴보면 변수를 선언하는 함수가 있다는 것이 매우 이상하다는 것을 알았습니다. 정말 눈살이 찌푸려지네요.

관련 정보