Zsh - Как называется расширение $ ~ variable, и отличается ли оно от переменной $ ~ ==? - PullRequest
1 голос
/ 21 сентября 2019

Я нашел эту оболочку sudo из списка рассылки Zsh :

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?Между прочим, кажется, что может быть произвольное число = с между $ и именем переменной, $~=t1 $=~t1 $~=====t1 все выглядит одинаково.

1 Ответ

1 голос
/ 22 сентября 2019

Спасибо @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.

Так что ~ позволяет использовать глобирование, которое заменяет шаблоны (спецификации) именами файлов.== гарантирует, что разделение слов отключено для строк в кавычках.

Например:

$ 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*
...