zsh가 "(:a)" 함수에 정의된 이 glob을 확장하지 않는 이유는 무엇입니까?

zsh가 "(:a)" 함수에 정의된 이 glob을 확장하지 않는 이유는 무엇입니까?

스크립트의 두 번째 줄은 실행을 통해 전역 확장을 트리거하는 경우에만 작동합니다 echo. 이유를 모르겠습니다. 다음은 일부 컨텍스트를 제공하는 명령과 실행입니다.

기능 정의:

~/ cat ~/.zsh/includes/ascii2gif
ascii2gif () {
        setopt extendedglob
        input=$(echo ${1}(:a))
        _path=${input:h}
        input_f=${input:t}
        output_f=${${input_f}:r}.gif
        cd $_path
        nerdctl run --rm -v $_path:/data asciinema/asciicast2gif -s 2 -t solarized-dark $input_f $output_f
}

ascii2gif 함수에 대한 함수 디버깅을 활성화합니다.

~/ typeset -f -t ascii2gif

디버깅 후 함수 실행:

~/ ascii2gif ./demo.cast
+ascii2gif:1> input=+ascii2gif:1> echo /Users/b/demo.cast
+ascii2gif:1> input=/Users/b/demo.cast
+ascii2gif:2> _path=/Users/b
+ascii2gif:3> input_f=demo.cast
+ascii2gif:4> output_f=demo.gif
+ascii2gif:5> cd /Users/b
+_direnv_hook:1> trap -- '' SIGINT
+_direnv_hook:2> /Users/b/homebrew/bin//direnv export zsh
+_direnv_hook:2> eval ''
+_direnv_hook:3> trap - SIGINT
+ascii2gif:6> nerdctl run --rm -v /Users/b:/data asciinema/asciicast2gif -s 2 -t solarized-dark demo.cast demo.gif
==> Loading demo.cast...
==> Spawning PhantomJS renderer...
==> Generating frame screenshots...
==> Combining 40 screenshots into GIF file...
==> Done.

확장 등을 강제로 시도했지만 input=${~1}(:a)소용이 없었습니다. 어떤 제안이 있으십니까? 분명히 스크립트는 작동하지만 최적은 아닌 것 같습니다.

답변1

그건 당신이 사용하려는 방식 때문이에요a수정자이는 와일드카드용이며 와일드카드는 발생하지 않습니다. 왜냐하면 와일드카드는 일반적으로 여러 단어를 생성하므로 단일 단어가 필요한 컨텍스트에서는 발생하지 않기 때문입니다. 따라서 명령 대체 내에서 발생하는 와일드카드에 의존하고 결과를 변수에 할당합니다.var=WORD

a수정자는 매개변수 확장에 사용될 수 있지만 다르게 적용되므로 다음을 시도해 볼 수 있습니다 .

input=${1:a}

예를 들어:

% cd /tmp
% foo() { input=${1:a}; typeset -p input; }
% foo some-file
typeset -g input=/tmp/some-file

답변2

/우무루~의답변이 문제를 해결하는 올바른 방법인 것처럼 보이지만 그 이유는확장되지 않는 점은 파일 이름 생성(와일드카드)이 스칼라 할당에서 발생하지 않는다는 것입니다(일반적으로 와일드카드는 여러 일치 항목을 반환할 수 있으므로 배열 할당에서 발생합니다).

에서 man zshoptions:

   GLOB_ASSIGN <C>
          If this option is set, filename generation  (globbing)  is  per‐
          formed on the right hand side of scalar parameter assignments of
          the form `name=pattern (e.g. `foo=*').  If the result  has  more
          than  one  word  the  parameter  will become an array with those
          words as arguments. This option is provided for  backwards  com‐
          patibility  only: globbing is always performed on the right hand
          side of array  assignments  of  the  form  `name=(value)'  (e.g.
          `foo=(*)')  and  this form is recommended for clarity; with this
          option set, it is not possible to  predict  whether  the  result
          will be an array or a scalar.

그래서

$ zsh -c 'f=${1}(:a); echo $f' zsh file.txt
file.txt(:a)

하지만

$ zsh -c 'f=(${1}(:a)); echo $f' zsh file.txt
/home/steeldriver/dir/file.txt

관련 정보