foo
私はいくつかの元の関数をオーバーライドし、実行中にその元の関数(またはそのコピー)を呼び出す関数を参照するために「オーバーライドラッパー」という表現を使用します。
これについてStack Exchangeスレッドを見つけました(例:これ)が、私の場合は、元のファイルfoo
と上書きされたファイルの両方を介してfoo
アクセスFPATH
して自動ロードできる必要があるという追加の要件があります。 (上書きされたバージョンが検索順序の前半に表示され、元のバージョンを隠すことができます。)
これを行う方法はありますか?
FWIW、私が作業している特定のシナリオでは、オーバーライドはfoo
ソースによって参照されるいくつかのグローバル変数にいくつかの非標準値を割り当てることによってアクションを実行します。
答え1
autoload
この関数を使用すると、ファイル名が関数名と一致する必要があるという制限なく、thisと同じ方法でファイルから関数コードをロードできます。
## load_from FILE FUNCTION_NAME
load_from () {
eval "$2 () { $(<$1) }"
}
ラッパーコードは以下の通りです。$^fpath/somefunction(N)
定義されたロードパスのリストに展開されます(すべてのエントリのリストに展開され、glob修飾子は既存のファイルに拡張を制限します)。これは、単一レイヤーラッパーとラッパーがある場合にのみ機能します。somefunction
$^fpath/somefunction
/dir/somefunction
/dir
$fpath
(N)
はいfパスから。
#autoload somefunction
local some_parameter=overridden_value
local autoload_files
autoload_files=($^fpath/somefunction(N))
load_from $autoload_files[2] somefunction_wrapped
somefunction_wrapped "$@"
答え2
私は、Debianでバイナリ/init.dファイル/スクリプトをラッパーに置き換えるために、長年にわたって本番でファイル転送を使用して大きな成功を収めました。
非表示にする元のファイルと同じ名前のラッパーを使用している場合は、そのパッケージの次の更新プログラムで置き換えるファイルがラッパーを上書きする可能性があります。
たとえば、ラッパーを追加するには、gcc
次のようにします。
sudo dpkg-divert --add --rename --divert /usr/bin/gcc.real /usr/bin/gcc
その後、包装紙をかぶせます/usr/bin/gcc
。
その時点から以前のgcc
バイナリは/usr/bin/gcc.real
、最も重要なことは、gcc
Debian APTシステムで実行/インストールされたすべての後続の更新がasの/usr/bin/gcc
新しいインスタンスをインストール/usr/bin/gcc.real
し、ラッパーを邪魔しないままにすることです。
~からman dpkg-divert
dpkg-divert はコンバージョンリストを設定および更新するユーティリティです。
ファイル転送は、dpkg(1)がファイルをその場所ではなく転送された場所にインストールするように強制する方法です。ファイルがクラッシュした場合は、Debianパッケージスクリプトを介した転送を使用して削除できます。システム管理者は、それを使用して特定のパッケージの構成ファイルを上書きするか、これらのファイルを含む最新バージョンのパッケージをインストールするときにdpkgに特定のファイル(「conffiles」と表示されない)を保存する必要がある場合はいつでも使用できます。
PS私はこの技術を使用して追加のオプションを追加し、BIND
スクリプトを初期化します。ISC-DHCP