. Ассоциативные массивы должны быть объявлены явно, с типом typeset -A
или что-то подобное ( объявить -A
или только для чтения -A
в bash). По умолчанию массив представляет собой «простой» массив с целочисленными индексами.Нечисловые индексы в массивах с целочисленным индексом интерпретируются как арифметические выражения, а неустановленные имена переменных в арифметических выражениях автоматически интерпретируются как 0, поэтому data = ([joe] = 30 [mary] = 25)
устанавливает data [0] = 30
, затем data [0] = 25
, и $ {data [something]}
- это элемент 0, который равен 25.
.
bash-4.3$ indexed=([a]=aye [b]=bee [x+1]=cee)
bash-4.3$ echo length=${#indexed[@]} a=${indexed[a]} b=${indexed[b]} x+1=${indexed[x+1]} 1=${indexed[1]}
length=2 a=bee b=bee x+1=cee 1=cee
bash-4.3$ typeset -A associative=([a]=aye [b]=bee [x+1]=cee)
bash-4.3$ echo length=${#associative[@]} a=${associative[a]} b=${associative[b]} x+1=${associative[x+1]} 1=${associative[1]}
length=3 a=aye b=bee x+1=cee 1=
Поскольку индексированный
является массивом с числовыми индексами, индексированный [a]
и индексированный [b]
оба индексируются [0]
], а проиндексировано [x + 1]
- это проиндексировано [1]
. В ассоциативном массиве то, что находится внутри скобок, анализируется как строка (с обычными расширениями, как в двойных кавычках, поэтому вы можете написать $ {ассоциативный [$ key]}
).
Если заключить в кавычки EOF
, переменные не будут раскрываться, как вы выяснили. Это задокументировано в разделе «Здесь документы» man bash
:
No parameter and variable expansion, command substitution, arithmetic
expansion, or pathname expansion is performed on word. If any part of
word is quoted, the delimiter is the result of quote removal on word,
and the lines in the here-document are not expanded. If word is
unquoted, all lines of the here-document are subjected to parameter
expansion, command substitution, and arithmetic expansion, the charac‐
ter sequence \<newline> is ignored, and \ must be used to quote the
characters \, $, and `.
Там также объясняется, что вы все еще можете использовать \
, вам просто нужно экранировать:\\
. Итак, поскольку вам нужны два \
, вам нужно экранировать каждый из них:\\\\
. Все это вместе:
#!/bin/bash
var="lalallalal"
tee file.tex <<EOF
text \\\\ text \\\\
$var
EOF
Кажется, вы хотите разрешить расширение только для части документа или только для некоторых специальных символов($
да, \
нет ). В первом случае вы можете разделить здесь -документ на два, а во втором случае позвольте мне предложить нестандартный -подход :трактовать \
как переменную:
var="lalallalal"
bs='\'; #backslash
tee file.tex <<EOF
text $bs$bs text $bs$bs
$var
EOF