私は私のzsh設定を調べてきましたが、zsh拡張構文のいくつかについて混乱しています。多くの内容は、次のリソースで見つかった内容に基づいています。
- http://zsh.sourceforge.net/Doc/Release/Expansion.html
- http://zsh.sourceforge.net/Doc/Release/Prompt-Expansion.html
- https://git.madduck.net/etc/zsh.git
- https://github.com/aspiers/shell-env/
- https://stackoverflow.com/questions/9901210/bash-source0-equivalent-in-zsh
構成
私の現在のzsh設定は次のとおりです。
~/.config/zsh/rcsentry
~/.zshenv symlink -> ~/.config/zsh/rcsentry
~/.config/zsh/.zshenv symlink -> ~/.config/zsh/rcsentry
~/.config/zsh/.zshrc symlink -> ~/.config/zsh/rcsentry
~/.config/zsh/.zlogin symlink -> ~/.config/zsh/rcsentry
~/.config/zsh/.zprofile symlink -> ~/.config/zsh/rcsentry
私のrcsentryは、現在それがどのように機能するかを正確に理解しようとしながら、最小限の状態に縮小されています。現在、これには以下が含まれます。
if [[ -o rcs ]]; then
rcs_fn="${(%):-%1N}"
rcs_fp="${(%):-%N}"
echo "rcs_fn: $rcs_fn"
echo "rcs_fp: $rcs_fp"
if [[ "$rcs_fn" == ".zshenv" ]]; then
echo "initializing XDG environment variables ..."
export XDG_CACHE_HOME="${XDG_CACHE_HOME:=$HOME/.cache}"
export XDG_CONFIG_HOME="${XDG_CONFIG:=$HOME/.config}"
export XDG_DATA_HOME="${XDG_DATA_HOME:=$HOME/.local/share}"
echo "initializing ZSH environment variables ..."
export ZDOTDIR="${ZDOTDIR:=$XDG_CONFIG_HOME/zsh}"
fi
unset rcs_fn
unset rcs_fp
fi
新しいシェルを実行すると、予想される結果が表示されます。
rcs_fn: .zshenv
rcs_fp: /Users/me/.zshenv
initializing XDG environment variables ...
initializing ZSH environment variables ...
rcs_fn: .zshrc
rcs_fp: /Users/me/.config/zsh/.zshrc
rcs_fn: .zlogin
rcs_fp: /Users/me/.config/zsh/.zlogin
文書化と説明
いくつかが混乱していますが、今では次のことを明確に理解するように制限したいと思います。
次の構文で始まります。
rcs_fn="${(%):-%1N}"
最初は、これが何を意味するのか分からなかった。文書を参照してこれを理解しようとするのも難しいです。私はそれが何であるかを知っていますが、構文を理解する方法を見つけようとしています。だからドキュメントから始めて、次のことを見つけました。
If the opening brace is directly followed by an opening parenthesis, the string
up to the matching closing parenthesis will be taken as a list of flags.
-- `man zshexpn` -> PARAMETER EXPANSION -> Parameter Expansion Flags
私はこれが(%)
パラメータ拡張に使用されたフラグのリストであることを示します。
% Expand all % escapes in the resulting words in the same way as in prompts
(see EXPANSION OF PROMPT SEQUENCES in zshmisc(1)). If this flag is given twice,
full prompt expansion is done on the resulting words, depending on the setting
of the PROMPT_PERCENT, PROMPT_SUBST and PROMPT_BANG options.
-- `man zshexpn` -> PARAMETER EXPANSION -> Parameter Expansion Flags
私はこれが(%)
実際にはパラメータ拡張フラグであることを示し、通常はプロンプト文字列に表示されるように、ステートメント全体をすべての%記号に拡張する必要があることをzshに指示します。
%N The name of the script, sourced file, or shell function that zsh is
currently executing, whichever was started most recently. If there is none,
this is equivalent to the parameter $0. An integer may follow the `%'
to specify a number of trailing path components to show; zero means the
full path. A negative integer specifies leading components.
-- `man zshmisc` -> SIMPLE PROMPT ESCAPES
前の前提を考慮すると、%1N
zshが現在実行中のコードを含むファイル名に拡張されるヒント拡張であることを示します。
${name:-word}
If name is set, or in the second form is non-null, then substitute its value;
otherwise substitute word. In the second form name may be omitted, in which
case word is always substituted.
-- `man zshexpn` -> PARAMETER EXPANSION
私はこれが文の完全な構文が単語の置換であることを示すことができると信じています。この場合、名前の値が空であると思うので(以前の唯一のものは:
拡張フラグのみです)、2番目の部分は%1N
自動的に挿入されます。しかし、これは私が構文を完全に間違って解釈したように奇妙に見えます。
7. Modifiers
Any modifiers, as specified by a trailing `#', `%', `/' (possibly doubled) or
by a set of modifiers of the form `:...' (see the section `Modifiers' in the
section `History Expansion'), are applied to the words of the value at this
level.
-- `man zshexpn` -> PARAMETER EXPANSION -> Parameter Expansion Flags -> Rules
After the optional word designator, you can add a sequence of one or more of the
following modifiers, each pre ceded by a `:'. These modifiers also work on the
result of filename generation and parameter expansion, except where noted.
-- `man zshexpn` -> HISTORY EXPANSION -> Modifiers
これをどのように解釈すべきか、関係があるかどうかはわかりません。前に単語修飾子があり、その後にファイル名を生成する構文(私にはわかりません)またはパラメータ拡張構文(しかし、再度はわかりません)が続くことを示すことができるようです:
。 %Nにリストされているパラメータ拡張セクションは表示されず、プロンプト拡張セクションでのみ表示されます。(@)
-%1N
一般化する
文書から読んだ内容によると、次のように分類されます。
:- indicates a word expansion, with word section empty and substitution `%1N`
(%) parameter expansion flag, indicating the expression should be expanded as
if it were in prompt expansion
%1N a prompt escape, which expands to the name of the file
${..} explicit parameter expansion, required for parameter expansion flag
テスト
これで遊んで構文を見つけたようです。更新されたrcsentryファイルには以下が含まれています。
if [[ -o rcs ]]; then
# The name of the file containing currently code that is currently executing.
rcs_fn="${(%):-%1N}"
# The path of the file containing currently code that is currently executing.
rcs_fp="${(%):-%N}"
# The resolved path of the file containing currently code that is currently
executing.
rcs_x1="${${(%):-%N}:A}"
# The resolved path of the parent directory of the file containing currently
# code that is currently executing.
rcs_x2="${${${(%):-%N}:A}:h}"
if [[ "$rcs_fn" == ".zshenv" ]]; then
# echo "initializing XDG environment variables ..."
export XDG_CACHE_HOME="${XDG_CACHE_HOME:=$HOME/.cache}"
export XDG_CONFIG_HOME="${XDG_CONFIG:=$HOME/.config}"
export XDG_DATA_HOME="${XDG_DATA_HOME:=$HOME/.local/share}"
# echo "initializing ZSH environment variables ..."
export ZDOTDIR="${ZDOTDIR:=$XDG_CONFIG_HOME/zsh}"
fi
echo "rcs_fn: $rcs_fn"
echo "rcs_fp: $rcs_fp"
echo "rcs_x1: $rcs_x1"
echo "rcs_x2: $rcs_x2"
unset rcs_fn
unset rcs_fp
fi
出力は予想通りです。
rcs_fn: .zshenv
rcs_fp: /Users/me/.zshenv
rcs_x1: /Users/me/.config/zsh/rcsentry
rcs_x2: /Users/me/.config/zsh
rcs_fn: .zshrc
rcs_fp: /Users/me/.config/zsh/.zshrc
rcs_x1: /Users/me/.config/zsh/rcsentry
rcs_x2: /Users/me/.config/zsh
rcs_fn: .zlogin
rcs_fp: /Users/me/.config/zsh/.zlogin
rcs_x1: /Users/me/.config/zsh/rcsentry
rcs_x2: /Users/me/.config/zsh
これらすべてに基づいて、私の考えはどのくらい間違っていましたか?
答え1
はい、あなたの説明は正しいです(長い質問を見てください)。
パラメータ拡張フラグはパラメータ拡張に適用されます。任意の文字列に適用するには、次のようにその文字列を変数に保存する必要があります。
var=%1N
filename=${(%)var}
または、(ハッキングとして)${var:-string}
パラメータ拡張を使用してそのvar
部分を空白のままにすることもできます${(%):-%1N}
。これは一般的なトリックです(参照:1
2
サム
4
5
6
7
8
9
10
11
12
13たとえば、ここでは、これは非常に読みにくいコードを生成します。あるいは、構文を使用するか、または${param+string}
など、常に設定されている()パラメータを使用できます。しかし、短くても読みやすくはありません。$-
$0
$#
${(%)-+%1N}
ここでも使えますprint -P %1N