假设我有一个这样的函数,它装饰参数字符串:
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