我有几个脚本/tmp/foo/bar.sh
,/tmp/foo/baz.sh
看起来像这样:
# /tmp/foo/bar.sh
alias -g __FILE__='${(%):-%x}'
alias -g __DIR__='${${(%):-%x}%/*}'
printf "sourcing %s\n" __FILE__
printf "about to source %s/baz.sh\n" __DIR__
. /tmp/foo/baz.sh
. $( printf "%s/baz.sh" __DIR__ ) # succeeds
. __DIR__"/baz.sh" # fails
# /tmp/foo/baz.sh
printf "sourcing %s\n" __FILE__
第一个脚本/tmp/foo/bar.sh
定义了几个全球的( -g
) 别名作为应扩展的咒语 (到第一个近似值!)到当前脚本的(调用)路径,并且它包含目录。然后它使用这些别名作为几个printf
命令中的参数。最后,它/tmp/foo/baz.sh
以三种不同的方式获取第二个脚本:
- 使用第二个脚本的文字路径;
__DIR__
通过printf
命令替换间接使用别名;- 直接使用
__DIR__
别名。
这是我获取第一个脚本时得到的结果:
% (/usr/bin/env -i zsh -fc '. /tmp/foo/bar.sh')
sourcing /tmp/foo/bar.sh
about to source /tmp/foo/baz.sh
sourcing /tmp/foo/baz.sh
sourcing /tmp/foo/baz.sh
/tmp/foo/bar.sh:.:11: no such file or directory: __DIR__/baz.sh
(歌舞是我尝试在尽可能简单的环境中/usr/bin/env
进行的。)/tmp/foo/bar.sh
看来 if__DIR__
后面紧跟的是/baz.sh
,那么它就不会被识别为别名,这也不无道理。该表单$( printf "%s/baz.sh" __DIR__ )
解决了这个问题,但它的长度和复杂性很大程度上得益于首先使用别名的好处。
有没有更方便的方法来使用别名构建第二个字符串的路径__DIR__
?
更一般地说,是否有一些通用的“语法技巧”来提醒解析器应将特定的字符序列视为别名?我的希望是让这样的全局别名更加类似于简单的(即一行、无参数等)C 预处理器宏。我想到的“语法技巧”的一个例子是类似下面的内容(均不起作用):
. {__DIR__}/baz.sh
. __DIR__"/baz.sh"
答案1
有一项功能允许将一个字符串替换为另一个仅带有一个额外字符的字符串:
__FILE__='${(%):-%x}'
__DIR__='${${(%):-%x}%/*}'
. $__DIR__/baz.sh
如果您确实不想定义变量,另一种方法是定义一个命名目录,该目录仅在单词开头的波形符后展开。这在您的示例中有效,但可能无法推广到您想要的所有情况。
hash -d __FILE__='${(%):-%x}'
hash -d __DIR__='${${(%):-%x}%/*}'
. ~__DIR__/baz.sh
答案2
好的,我找到了一个合适的解决方案,如下所示
# /tmp/foo/bar.sh
alias -g __FILE__='echo "${(%):-%x}"'
alias -g __DIR__='echo "${${(%):-%x}%/*}"'
printf "sourcing %s\n" $(__FILE__)
printf "about to source %s/baz.sh\n" $(__DIR__)
. $(__DIR__)/baz.sh # succeeds