関数を新しいスクリプトに移動

関数を新しいスクリプトに移動

$val入りa ()ますが目立たない方法はありますかb ()

set -u -e -o pipefail


a () {
  local +x val="myval"
  echo "in a: VAL= $val"
  b
}

b () {
  echo "in b: VAL= $val"
}

a

生産:

in a: VAL= myval
in b: VAL= myval  # This should not happen.

変数が他の関数に表示されないようにするために、サブシェルを使用する代わりにlocal/オプションを使用したいと思います。typeset

私が確認した手動(機能部分、組版部分)方法はないようです。しかし、私は簡単に何かを逃すことができました。

答え1

b変数を制限するためにサブシェルを使用する代わりに、新しいプロセスとして実行できます。これにより、エクスポートするように選択した変数以外の呼び出し元の変数にアクセスできなくなります。

関数を新しいスクリプトに移動

単一の関数のみが必要な場合は、関数全体を別のスクリプトに移動してください。

b:

#!/usr/bin/env mksh
set -u -e -o pipefail

echo "in b: VAL= $val"

出力:

in a: VAL= myval
./b[4]: val: parameter not set

ラッパー関数の使用

この機能を必要とする関数が多い場合は、その関数をすべて1つのファイルに移動し、ソースコードと実行のためのラッパー関数を含めることができます。

funcs:

#long options not passed on by -$-
set -o pipefail

#execute function without inheriting environment variables
function ni () {
  WHERE="${_%/*}"
  mksh -$- -c "source $WHERE/funcs ; $*"
}

function a () {
  local +x val="myval"
  echo "in a: VAL= $val"
  ni b
}

function b () {
  echo "in b: VAL= $val"
}

この「ライブラリ」はsource基本スクリプトからインポートする必要があります。

#!/usr/bin/env mksh

set -e -u -o pipefail

WHERE="${_%/*}"
source $WHERE/funcs

a

欠点は、エラーの場所(スクリプトと行番号)を失う可能性があることです。

in a: VAL= myval
mksh: val: parameter not set

答え2

いいえ。

しかし、、呼び出しがb終了呼び出しであり、その引数を「のみ」構成する必要がある場合は、これを行う方法があります。このメソッドは、「クラスパスの検索とJARの実行」スクリプトで使用されました。

function a {
    local val …

    # do something with local variables

    # construct arguments by setting the global variable _ to it
    set -A _ -- b arg1…
    # could even unset -f a here
}
a
"${_[@]}"

存在する私のスクリプト外部コマンドを呼び出すときは最後の行を使用しexec "${_[@]}"、エクスポートされた環境変数が誤って汚染されるのを防ぐためにローカル変数技術を使用します。

たぶんこれは役に立ちますか?

完全な公開:私はmksh開発者です。

関連情報