引数リストに関数呼び出しを簡単に保つ方法は?

引数リストに関数呼び出しを簡単に保つ方法は?

パラメータ文字列を装飾する次の関数があるとします。

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

関連情報