一部の機能を含む.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
/ ifzsh
sは入れ子にすることはできません(とにかくここでは意味がありません)。
しかし、引用の構文解析は環境変数で別々に行われるようにman
見えMANPAGER
(シェルを呼び出す代わりに)引用形式をサポートしていない$SHELL
ようです。引用が間違っています。代わりに、bashバージョンのように一重引用符を使用し、引用符の外側で一重引用符をエスケープする方法を使用してください。$'...'
q+
qq
\'
¹rcquotes
このオプションを有効にしないと、''
à laが代わりに使用されます。関数内に合理的なローカルオプションセットを持つことを関数の先頭にrc
追加すると、emulate -L zsh
関数が実行されずに定義されたときにオプションを無効にする必要があるため、役に立ちません。