zshが "(:a)"関数で定義されたこのglobを拡張しないのはなぜですか?

zshが "(:a)"関数で定義されたこのglobを拡張しないのはなぜですか?

スクリプトの2行目は、実行を通じてグローバル拡張をトリガーする場合にのみ機能します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

関連情報