だから私はそれを使い始めましたzsh
。私はそれがすべて好きだった。とても素敵でスムーズに見え、現在の作業ディレクトリと実際のコマンドラインが別の行にあるという事実は良いですが、同時に少し遅くなる可能性zsh
があることも発見しましたbash
。特にテキストを印刷する場合はさらにそうです。画面。
私が好きなのはzsh
私と一緒に働くことです.bashrc
。
それでも苦情が一つあります。すべてがうまく機能しますが、エクスポートシステムがどのように機能するかわかりません。
..bashrc
export -f
zshではエクスポートについて言及していないようです。自動的にロードされますか?これら2つは同じですか?私はこれを見つけるのに苦労しています。
答え1
関数を含む環境変数はbashハッキングです。 Zshに似たものはありません。ほんの数行のコードで同様のことができます。環境変数には、以前のバージョンのbashが含まれています。シェルショック名前は関数名で、その値() {
の後に関数コードが続く変数に関数コードを格納することがわかりました}
。次のコードを使用してこのエンコーディングで変数を取得し、bashのようなものを試すことができます。設定して実行してください。 zshはすべてのbash機能をエミュレートすることはできないので、もう少し近づくだけです(たとえば、$foo
値を分割し、ワイルドカードを拡張し、配列を0から始めるようにするなど)。
bash_function_preamble='
emulate -LR ksh
'
for name in ${(k)parameters}; do
[[ "-$parameters[name]-" = *-export-* ]] || continue
[[ ${(P)name} = '() {'*'}' ]] || continue
((! $+builtins[$name])) || continue
functions[$name]=$bash_function_preamble${${${(P)name}#"() {"}%"}"}
done
(ようにスティーブン・チャジェラスShellshockの最初の発見者は、関数定義が間違っていると、この回答の以前のバージョンがこの時点で潜在的に任意のコードを実行できることを指摘しました。このバージョンはそうではありませんが、もちろんコマンドを実行すると、環境からインポートされた関数になる可能性があります。 )
Shellshock 以降のバージョンの bashBASH_FUNC_myfunc%%
エンコード機能は、無効な変数名 (例:) がある環境で実行されます。 zsh は環境からこれらの変数名を抽出するためのインタフェースを提供しないため、これにより信頼性の高い解析が難しくなります。
私はこれをお勧めしません。スクリプトからエクスポートされた関数に頼るのは悪い考えです。スクリプトに見えない依存関係を生成します。機能のない環境(他のコンピュータ、クローン操作、シェル初期化ファイルの変更後...)でスクリプトを実行すると、スクリプトは機能しなくなります。代わりに、すべての関数を1つ以上の別々のファイル(に似ています~/lib/shell/foo.sh
)に保存し、スクリプトが使用する関数をインポートしてスクリプトを起動します(. ~/lib/shell/foo.sh
)。これにより、変更すると、foo.sh
どのスクリプトがそれに依存しているかを簡単に検索できます。スクリプトをコピーすると、必要な補助ファイルを簡単に見つけることができます。
Zsh(およびそれ以前のksh)は、それを使用するスクリプトから関数を自動的にロードする方法を提供し、それをより便利にします。制限は、ファイルごとに1つの機能しか配置できないことです。関数を自動ロードとして宣言し、関数定義をfunction_nameというファイルに保存します。このファイルをリストされたディレクトリに配置します$fpath
(FPATH
環境変数を介して設定できます)。スクリプトからautoload -U foo
。
また、zshはスクリプトをコンパイルして解析時間を節約できます。呼ぶzcompile
スクリプトをコンパイルします。拡張子を持つファイルが作成されます.zwc
。このファイルが存在する場合、autoload
ソースコードの代わりにコンパイルされたファイルがロードされます。あなたはそれを使用することができますzrecompile
機能ディレクトリ内のすべての関数定義を(再)コンパイルします。
答え2
関数宣言を入れると.zshenv、何の努力もせずにスクリプトで関数を使用できます。
答え3
私が読んだことはすべて自動的に関数をインポートするのが悪い考えであることを示唆しているので、スクリプトをサブシェルから簡単にアクセスできる別のファイルに抽出することにしました。
共有ファイルを呼び出しました.zshared
。
# ~/.zshared
function say-hello() {
echo "Hello, $1\!"
}
私からソースを明らかにします.zshrc
。
# ~/.zshrc
source ~/.zshared
これらの機能にアクセスする必要があるスクリプトでは.zshared
。
#!/usr/bin/env zsh
source ~/.zshared
say-hello "David" # Hello, David!
最初にスクリプトを更新するには少し作業が必要ですが、大きなオーバーヘッドなしで1つの場所で関数を定義できます。