bashがzshコードを解析しないようにする方法はありますか?

bashがzshコードを解析しないようにする方法はありますか?

一部の機能を含む.bashrcファイルがあります。.zshrc以前は、各シェルに対して2つの別々のファイルでしたが、今ではファイルがほぼ同じで、単一の関数ファイルを管理する方が簡単なので、単一のファイルを使用しています。

両方のシェルには異なる機能があるので、正しい文が使用されるように条件文を使用できると思いました。

[[ $BASH_VERSION ]] && shell=bash
[[ $ZSH_VERSION ]] && shell=zsh

# Search man page for string
if [[ $shell == bash ]]; then
  mans() {
    local q="\'"
    local q_pattern="'${1//$q/$q\\$q$q}'"
    local MANPAGER="less -+MFX -p $q_pattern"
    man "$2"
  }
elif [[ $shell == zsh ]]; then
  mans() MANPAGER="less -+MFX -p ${(q+)1}" man $2
fi

これはzshではうまくいくようですが、bashに切り替えるとbashで使用してはいけませんが、zsh行でエラーが発生します。その行を解析するのを防ぐ方法はありますか?

ベストアンサー1

ifbashたとえば、次のようないくつかのifzshエイリアスを定義できますendif

alias if{ba,z}sh=':||:<<"endif"' endif=
if [[ -n $BASH_VERSION ]]; then
  alias ifbash=
  shopt -s expand_aliases
elif [[ -n $ZSH_VERSION ]]; then
  alias ifzsh=
fi

ifbash
f() { echo bash; }
endif

ifzsh
f() echo ${(q+):-zsh}
endif

:||:<<"MARKER"...はMARKERコードセクションをコメントアウトする慣用的な方法です。これはstdinでhere-docを使用して組み込みのnoopを:<<"MARKER"実行するのと似ていますが、さらに2番目のドキュメントは実行されず、here-documentも生成されず、解析のみです。::||:

インデントをしてはendifいけませんし、後ろに何も追加してはいけません。完全な行を構成する必要があります。ifbash/ ifzshsは入れ子にすることはできません(とにかくここでは意味がありません)。

しかし、引用の構文解析は環境変数で別々に行われるようにman見えMANPAGER(シェルを呼び出す代わりに)引用形式をサポートしていない$SHELLようです。引用が間違っています。代わりに、bashバージョンのように一重引用符を使用し、引用符の外側で一重引用符をエスケープする方法を使用してください。$'...'q+qq\'


¹rcquotesこのオプションを有効にしないと、''à laが代わりに使用されます。関数内に合理的なローカルオプションセットを持つことを関数の先頭にrc追加すると、emulate -L zsh関数が実行されずに定義されたときにオプションを無効にする必要があるため、役に立ちません。

おすすめ記事