인수 목록에 함수 호출을 쉽게 유지하는 방법은 무엇입니까?

인수 목록에 함수 호출을 쉽게 유지하는 방법은 무엇입니까?

매개변수 문자열을 장식하는 다음과 같은 함수가 있다고 가정해 보겠습니다.

blue() {
  echo -e "\033[94m$@\033[39m"
}
bold() {
  echo -e "\033[1m$@\033[21m"
}

이제 다음과 같이 사용할 수 있습니다.

bold "haha"
blue "haha"

그러나 이들을 결합하려면 $()또는 백틱을 사용하여 `중첩 해야 합니다.

bold `blue haha`

blink다음과 같은 문자열 장식 기능이 더 많거나 add_prefix모두 결합하기 어려울 경우:

blink(){
  echo -e "\033[5m$@\033[25m"
}
add_prefix(){
  echo -e "\033[4mNote:\033[24m $@"
}

많은 백틱을 중첩해야 하며 다음을 수행해야 합니다 $().

add_prefix $(blink `blue $(bold haha)`)
add_prefix $(blink $(blue $(bold haha)))

혼란스럽고 사용하기 어렵습니다.

인수 목록에 함수 호출을 유지하는 방법이 있나요? 아니면 함수를 구성하는 다른 권장 방법이 있나요?

답변1

내장된 bash 명령을 사용하여 type제공된 체인이 함수인지 확인할 수 있습니다.

$ blue () { echo -e "\033[94m$@\033[39m" }
$ type -t blue
function
$ type -t foo
$

따라서 파란색 기능은 다음과 같습니다.

blue () {
    echo -ne "\033[94m"
    if [[ $(type -t "$1") == "function" ]]; then # first arg is a function name ?
        "$@"                                     # yes: exec
    else
        echo -ne "$@"                            # no: echo
    fi
}

간단한 경우에는 괜찮습니다.

$ blue "bold haha"

파란색으로 에코 됩니다 bold haha. 이는 arg 1이 "bold haha"이고

$ blue bold haha

이것은 굵은 글씨와 파란색으로 표시됩니다 haha. 이는 arg 1이 "굵은" 함수 이름이기 때문에 예상되는 현상입니다.

하지만 다음과 같은 것을 원한다면 이것을 사용할 수 없습니다

blue bold "i" red "want" blue "some" blink "fun"

넌 옳은 것도 가질 수 없어

$ blue bold blink haha

"blink haha"가 1(문자 그대로 에코되어야 함) 인수인지 2(그리고 haha는 깜박여야 함) 인수인지 파란색으로 알 수 없기 때문입니다.

이러한 이유로 꼭 함수를 사용하고 싶다면 다른 접근 방식을 제안합니다. 함수를 "구성"하려고 하지 마세요. 제공된 문자열이 함수 이름인지 아니면 리터럴 문자열인지 확인할 수 없습니다. 파란색, 빨간색 또는 원하는 색상 기능을 작성하고 최종 색상 기능을 작성하면 깜박임 및 굵은 기능에도 동일하게 적용됩니다.

blue ()     { echo -ne "\033[94m"; } # -n avoid line break
red ()      { echo -ne "\033[31m"; }
endcolor () { echo -ne "\033[39m"; }
bold ()     { echo -ne "\033[1m" ; }
endbold ()  { echo -ne "\033[21m"; }
blink ()    { echo -ne "\033[5m" ; }
endblink () { echo -ne "\033[25m"; }

이제 당신이 원하는 것은 무엇이든 할 수 있습니다

$ blue; bold; blink; echo -n "I "; endblink; red; echo -n "want "; endcolor; echo -n "some "; endbold; blue; echo "fun."; endcolor; endblink; endbold

굵은 파란색으로 깜박이는 "I", 빨간색으로 "Want", 흰색으로 "Some", 파란색으로 "Fun"이 깜박이는 모습을 보여줍니다.

완전성을 위해 가장 간단한 솔루션을 추가해야 합니다. 즉, 함수를 사용하지 말고 매개변수를 사용하십시오.

$ blue="\033[94m"
$ red="\033[31m"
$ endcolor="\033[39m"
$ bold="\033[1m"
$ endbold="\033[21m"
$ blink="\033[5m"
$ endblink="\033[25m"
$ echo -e "${blue}${bold}${blink}I ${endblink}${red}want ${endcolor}some ${endbold}${blue}fun.${endcolor}${endblink}${endbold}"

답변2

각 단계의 출력을 변수에 저장할 수 있습니다.

string="haha"
string=$(bold "$string")
string=$(blue "$string")
string=$(blink "$string")
string=$(add_prefix "$string")

모든 단계에서 변수를 참조하세요.


또 다른 방법은 입력을 받는 제어 함수와 적용하려는 함수를 작성하는 것입니다.

apply() {
    local input=$1
    for func in "${@:2}"; do
        # extra credit: verify $func is a function
        input=$( "$func" "$input" )
    done
    echo "$input"
}

apply "haha" bold blue blink app_prefix

관련 정보