zsh - Zsh - 什么是 $~variable 扩展,它与 $~==variable 有什么不同?
问题描述
我从Zsh 邮件列表中找到了这个 sudo 包装器:
alias sudo='noglob do_sudo '
function do_sudo
{
integer glob=1
local -a run
run=( command sudo )
if [[ $# -gt 1 && $1 = -u ]]; then
run+=($1 $2)
shift ; shift
fi
(($# == 0)) && 1=/bin/zsh
while (($#)); do
case "$1" in
command|exec|-) shift; break ;;
nocorrect) shift ;;
noglob) glob=0; shift ;;
*) break ;;
esac
done
if ((glob)); then
PATH="/sbin:/usr/sbin:/usr/local/sbin:$PATH" $run $~==*
else
PATH="/sbin:/usr/sbin:/usr/local/sbin:$PATH" $run $==*
fi
}
它用于$~==*
扩展文件模式。这种扩展叫什么?它记录在哪里?(真的不知道如何搜索这个,'美元波浪号扩展','文件名扩展','波浪号扩展'都给了我一些不相关的结果......)
我注意到这实际上$~var
也有效,例如
$ touch foo bar
$ t1='fo*'
$ echo $~t1
foo
$ t2=('fo*' 'ba*')
$ echo $~t2
foo bar
和 有什么不同$~==t1
吗?顺便说一句,变量名和变量名之间似乎可以有任意数量的=
s ,看起来都一样。$
$~=t1
$=~t1
$~=====t1
解决方案
感谢@chepner 的提示。这是我在zshexpn
手册中找到的:
${=spec}
Perform word splitting using the rules for SH_WORD_SPLIT during the evaluation of spec, but regardless of whether the parameter appears in double quotes; if the `=' is
doubled, turn it off. This forces parameter expansions to be split into separate words before substitution, using IFS as a delimiter. This is done by default in most
other shells.
Note that splitting is applied to word in the assignment forms of spec before the assignment to name is performed. This affects the result of array assignments with the A
flag.
${~spec}
Turn on the GLOB_SUBST option for the evaluation of spec; if the `~' is doubled, turn it off. When this option is set, the string resulting from the expansion will be in‐
terpreted as a pattern anywhere that is possible, such as in filename expansion and filename generation and pattern-matching contexts like the right hand side of the `='
and `!=' operators in conditions.
In nested substitutions, note that the effect of the ~ applies to the result of the current level of substitution. A surrounding pattern operation on the result may can‐
cel it. Hence, for example, if the parameter foo is set to *, ${~foo//\*/*.c} is substituted by the pattern *.c, which may be expanded by filename generation, but
${${~foo}//\*/*.c} substitutes to the string *.c, which will not be further expanded.
因此,~
启用将模式(规范)替换为文件名的 globbing。==
确保对引号中的字符串禁用分词。
例如:
$ touch foo bar
$ spec='fo* ba*'
$ echo $~spec
zsh: no matches found: fo* ba*
$ echo $~=spec
foo bar
$ echo $~==spec
zsh: no matches found: fo* ba*
$ function test1() { printf '1=%s 2=%s\n' $1 $2; }
$ test1 $spec
1=fo* ba* 2=
$ test1 $~spec
zsh: no matches found: fo* ba*
$ test1 $~=spec
1=foo 2=bar
$ test1 $~==spec
zsh: no matches found: fo* ba*
$ test1 $=spec
1=fo* 2=ba*
推荐阅读
- javascript - 为什么我的 localStorage 没有在刷新时保存
- visual-studio-code - 为什么不实时服务器扩展在 VScode 中不起作用?
- java - 如何在android上设置相机方向锁定为纵向
- laravel - 如何使用cropperjs修复CORS策略?
- repository - 仅从测试存储库 apt-install 特定软件包
- flask - 带有 mongoengine 的 APScheduler 在作业中传递旧值
- ms-access - PowerPivot 连接多个带有日期的表的问题
- arrays - Bash Mapfile 或在 grep 文件内容时读取
- javascript - 如何将行添加到第一个空行?带有 chrome 扩展的 Google 电子表格 API
- angular - 执行可信脚本