Учитывая, что Bash Reference Manual в разделе 3.5.3 Shell Parameter Expansion
говорит:
${!name[@]} ${!name[*]}
Если имя переменной массива, расширяется список индексов массива (ключи), назначенные по имени. Если имя не является массивом, оно увеличивается до 0, если имя задано, а null - в противном случае. Когда используется «@», и расширение появляется в двойных кавычках, каждая клавиша расширяется до отдельного слова.
и
$ {параметр: -слово}
Если параметр не установлен или нулевой, раскрытие слова заменены. В противном случае значение параметра заменяется.
и
$ {параметр: + слово}
Если параметр является нулевым или не установлено, ничего не подменяется, в противном случае раскрытие слова заменены.
Может кто-то объяснить выход из следующих расширений мне:
$ bash --version
GNU bash, version 3.2.25(1)-release (x86_64-redhat-linux-gnu)
Copyright (C) 2005 Free Software Foundation, Inc.
$ cat hm.sh
p() {
printf "%-11s : f=%1s : " "$*" "$f"
eval printf \'%1s :\\n\' "[email protected]"
}
p '$f'
p '${!f[@]}'
p '${!f[@]:-b}'
echo "echo: ${!f[@]:-b} :"
p '${!f[@]:+b}'
echo "echo: ${!f[@]:+b} :"
f=f
p '$f'
p '${!f[@]}'
p '${!f[@]:-b}'
echo "echo: ${!f[@]:-b} :"
p '${!f[@]:+b}'
echo "echo: ${!f[@]:+b} :"
f=t
p '$f'
p '${!f[@]}'
p '${!f[@]:-b}'
echo "echo: ${!f[@]:-b} :"
p '${!f[@]:+b}'
echo "echo: ${!f[@]:+b} :"
$ bash hm.sh
$f : f= : :
${!f[@]} : f= : :
${!f[@]:-b} : f= : b :
echo: b :
${!f[@]:+b} : f= : :
echo: :
$f : f=f : f :
${!f[@]} : f=f : 0 :
${!f[@]:-b} : f=f : f :
echo: f :
${!f[@]:+b} : f=f : b :
echo: b :
$f : f=t : t :
${!f[@]} : f=t : 0 :
${!f[@]:-b} : f=t : b :
echo: b :
${!f[@]:+b} : f=t : :
echo: :
Именно поэтому делать содержания переменных в изменении вопроса, как ${!name[@]:-default}
и ${!name[@]:+alt}
разложения расширения, когда содержание делать не изменение как расширение ${!name[@]}
расширяет?
А, вы предполагаете, что оболочка выполняет '$ {! F [@]: - b}' -> '$ {f [@]: - b}' и '$ {! F [@]: -b} '->' $ {t [@]: - b} ', а затем (эффективно) игнорирование' [@] 'as' $ {not_array [@]} 'такое же, как' $ {not_array} ' а затем увидеть '$ {f: -b}' или '$ {t: -b}'? Это не первый раз, когда я пожелал поэтапного расширения отладки в оболочке. –
@EtanReisner: Если в вашем тесте вы устанавливаете 'f = t t = u', что вы видите? Но я не знаю, что '[@]' игнорируется, точно.Кажется, что это игнорируется только в том случае, когда 'f' является скаляром. Afaics, если f является массивом, даже одного элемента, косвенная неудача и значение по умолчанию заменяется. – rici
't',' 0', 'u',' b' для четырех расширений, которые соответствуют вашим объяснениям. И да, я специально говорил о скалярном/не-массивом случае для '[@]' игнорируется (что я также не понимаю, но это другая проблема). Случай массива - это расширение нормальных значений (которое соответствует тому, что вы видели и чего я ожидаю). Я не пробовал эту косвенность/расширение с помощью массивов, потому что это было не то, с чем я играл в то время. –