나는 내 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
나는 이것이 진술의 전체 구문이 단어 대체임을 나타낼 수 있다고 믿습니다. 이 경우 이름 값이 비어 있다고 생각하므로(이전의 유일한 것은 :
확장 플래그뿐임) 두 번째 부분이 %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