連想 - Bash: パラメータとして関数を渡す



linux bash (5)

evalはそれを達成するための唯一の方法でしょう。 唯一の本当の欠点は、悪意のあるものは渡されず、呼び出される関数だけが呼び出されることを確認する必要があるため( ';'のような厄介な文字がないことを確認する必要があるため)、セキュリティの側面です。それにも同様に)。

だから、もしあなたがコードを呼び出す人なら、evalがそれを行う唯一の方法だろう。 サブコマンド($()と ``)も関与する可能性が高い他の形式のevalがありますが、安全ではなく、より高価です。

https://src-bin.com

私はBashでパラメータとして関数を渡す必要があります。 たとえば、次のコード:

function x() {
  echo "Hello world"
}

function around() {
  echo "before"
  eval $1
  echo "after"
}

around x

出力する必要があります:

before
Hello world
after

私はevalがその文脈では正しくないことを知っていますが、それは単なる例です:)

何か案が?


Answer #1

evalを使う必要はありません

function x() {
  echo "Hello world"
}

function around() {
  echo "before"
  var=$($1)
  echo "after $var"
}

around x

Answer #2

より良いアプローチは、関数内のローカル変数を使用することです。 問題は、呼び出し元にどのように結果を返すかになります。 1つのメカニズムはコマンド置換を使用することです。

function myfunc()
{
    local  myresult='some value'
    echo "$myresult"
}

result=$(myfunc)   # or result=`myfunc`
echo $result

ここで結果はstdoutに出力され、呼び出し元はコマンド置換を使用して変数の値を取得します。 この変数は必要に応じて使用できます。


Answer #3

文字列以外の関数には何も渡すことはできません。 プロセスの置換は、偽のものを並べ替えることができます。 Bashはコマンドが完了するまでFIFOを開いたままにします。

ここで素早く愚かなことがあります

foldl() {
    echo $(($(</dev/stdin)$2))
} < <(tr '\n' "$1" <$3)

# Sum 20 random ints from 0-999
foldl + 0 <(while ((n=RANDOM%999,x++<20)); do echo $n; done)

関数をエクスポートすることはできますが、これは最初に表示されるほど興味深いものではありません。 私はそれがスクリプトやスクリプトを実行する他のプログラムにアクセスできるデバッグ機能を作成するために主に役立つことがわかります。

(
    id() {
        "[email protected]"
    }

    export -f id
    exec bash -c 'echowrap() { echo "$1"; }; id echowrap hi'
)

idは、関数の名前(環境内の直列化から自動的にインポートされた)とその引数である文字列を取得します。

Pumbaa80の別の回答へのコメントも良いです( eval $(declare -F "$1") )。しかし、配列ではなく、関数ではなく、常にグローバルなので、便利です。 これを関数内で実行するのであれば、それを再定義するだけなので、何の効果もありません。 これは、現在のスコープでバインドされているものに依存して、クロージャーまたは部分的な関数または「関数インスタンス」を作成するために使用することはできません。 せいぜいこれは、他の場所で再定義された文字列に関数定義を格納するために使用できますが、これらの関数はコースevalが使用されていない限りハードコード化することもできます

基本的にBashはこのように使うことはできません。


Answer #4

関数名や引数の評価を遅らせるなど、何も気にする必要がない場合は、 evalは必要ありません。

function x()      { echo "Hello world";          }
function around() { echo before; $1; echo after; }

around x

あなたが望むことをします。 このように関数とその引数を渡すことさえできます:

function x()      { echo "x(): Passed $1 and $2";  }
function around() { echo before; "[email protected]"; echo after; }

around x 1st 2nd

プリント

before
x(): Passed 1st and 2nd
after




parameter-passing