ZSHログイン時にprecmd_functionsに機能を追加し、重複を避けたいです。 /etc/zprofileは/etc/profileをソースにし、/etc/profile.d/の下のすべての*.shスクリプトをソースにするので、私の解決策はinitスクリプトを/etc/profile.dに追加することでした。 。 Bashとの互換性を維持するために、自動ソーススクリプトnew_script.sh
は次のとおりです。
# zsh user
if [ -n "$ZSH_VERSION" ]; then
source /etc/profile.d/new_script.zsh
# bash user
elif [ -n "$BASH_VERSION" ]; then
source /etc/profile.d/new_script.bash
fi
これまではすべて緑色ですが、new_script.zshは奇妙に動作します。その内容は次のとおりです。
...
if (( $precmd_functions[(I)audit_hook] )); then
hook_exist=true
else
hook_exist=false
fi
zshを使用してログインして手動でインポートすると、問題なく実行されます。ただし、ログイン初期化中に自動的にインポートすると、bad output format specification
行に報告されますif (( $precmd_functions...
。
その場合、initにログインしたときにのみこのエラーが報告され、手動インポートスクリプトでは報告されないのはなぜですか?
答え1
以下のファイルは/etc/profile.d
sh構文で書かれると予想されるので、ソース/etc/zprofile
のコードは/etc/profile.d/*
おそらく次のshまたはashエミュレーションモードでこれを行うように配置されていますemulate ksh -c '. /etc/profile'
。
shとzshの構文の違いの1つは、$foo[bar]
zshでは配列変数の逆参照として解析されますが、sh(およびbashやzshなどの互換シェル)では、単一文字のglobが後に続く文字列変数であることです(したがってshとしてtouch somefilename1 somefilename2 somefilename3; var=somefilename; echo $var[12]
印刷されますsomefilename1 somefilename2
/bash /ksh、しかしe
zsh に無し)。 zshがshまたはkshエミュレーションモードのとき、zsh_arrays
$precmd_functions[(I)audit_hook]
オプションが有効になっているため、アレイアクセスでは確認されません。precmd_functions
この時点では空であるため(そうでなければ他のエラーが発生する可能性が高い)、算術式はになります[(I)audit_hook]
。 zshのブラケット部分算術表現出力フォーマット仕様は、出力が異なる基準でフォーマットされるように指示する出力フォーマット仕様です(いくつかの異なる可能性のうち、これが出力ベースの仕様ではない理由です)。 zshが開く括弧を見ると、出力形式の仕様を解析する準備ができますが失敗します。
zsh固有のコードを作成し/etc/profile.d
てzsh構文を使用する場合は、zsh構文を使用するようにzshに明示的に指示します。
if [ -n "$ZSH_VERSION" ]; then
emulate zsh -c 'source /etc/profile.d/new_script.zsh'
fi
または、すべてのコードをnew_script.zsh
関数に入れてemulate -L zsh
関数の上部にあります。 (関数の外に置かないでくださいemulate -L …
。ソーススクリプトにローカルではありません。)