如何轻松地将函数调用保留在参数列表中?

如何轻松地将函数调用保留在参数列表中?

假设我有一个这样的函数,它装饰参数字符串:

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

现在我可以像这样使用它:

bold "haha"
blue "haha"

但如果我想组合它们,我必须使用$()或反引号`来嵌套它们:

bold `blue haha`

blink如果我有更多像or 这样的字符串装饰函数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

您可以使用type内置的 bash 命令来查明提供的链是否是一个函数:

$ 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 是“粗体哈哈”并且

$ blue bold haha

将以粗体和蓝色回显haha,这也是预期的,因为 arg 1 是“粗体”函数名称。

但如果你想要类似的东西,你就不能使用这个

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

你甚至不能拥有正确的东西

$ blue bold blink haha

因为你无法告诉 blue “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

其中显示了一个以粗体蓝色闪烁的“我”,其中有红色“想要”、白色“一些”和蓝色“乐趣”。

为了完整性,我必须添加最简单的解决方案:不要使用函数,使用参数。

$ 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

相关内容