首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么zsh不展开函数‘(:a)中定义的这个glob

为什么zsh不展开函数‘(:a)中定义的这个glob
EN

Unix & Linux用户
提问于 2022-03-30 11:48:17
回答 2查看 379关注 0票数 6

只有当我通过执行echo触发glob扩展时,脚本的第二行才能工作。我不明白为什么。这是命令,它的执行给出了一些上下文。

功能定义:

代码语言:javascript
复制
~/ 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函数的函数调试。

代码语言:javascript
复制
~/ typeset -f -t ascii2gif

调试的函数执行:

代码语言:javascript
复制
~/ 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)等,但没有任何效果。有什么建议吗?显然,该脚本工作,但似乎不太理想。

EN

回答 2

Unix & Linux用户

回答已采纳

发布于 2022-03-30 12:09:09

这是因为您在这里尝试使用这个a修饰符的方式是为了全局化,而在var=WORD中没有进行全局化(因为全局化通常会导致多个单词,因此它不会发生在期望一个单词的上下文中)。因此,您依赖于命令替换内部的全局化,然后将结果赋值给变量。

由于a修饰符可以用于参数展开,但使用不同的应用方法,您可以尝试这样做:

代码语言:javascript
复制
input=${1:a}

例如:

代码语言:javascript
复制
% cd /tmp
% foo() { input=${1:a}; typeset -p input; }
% foo some-file
typeset -g input=/tmp/some-file
票数 5
EN

Unix & Linux用户

发布于 2022-03-30 12:21:20

/u muru's 回答看起来是正确的方法,但是它没有扩展的原因是文件名生成(globbing)不发生在标量赋值中(它在数组赋值中进行,因为全局-通常可能返回多个匹配):

来自man zshoptions

GLOB\_ASSIGN 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.

所以

代码语言:javascript
复制
$ zsh -c 'f=${1}(:a); echo $f' zsh file.txt
file.txt(:a)

代码语言:javascript
复制
$ zsh -c 'f=(${1}(:a)); echo $f' zsh file.txt
/home/steeldriver/dir/file.txt
票数 3
EN
页面原文内容由Unix & Linux提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://unix.stackexchange.com/questions/697349

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档