Поскольку ваша команда Awk указана в двойных кавычках, внутренние знаки доллара подлежат особой обработке: $2
рассматривается как замена параметров вашей оболочкой, и поэтому элемент массива не хранит текст $2
а скорее его расширение.Интерпретатор Awk никогда не видит синтаксис $2
.
Однако у вас есть вторая проблема в вашем диспетчере команд.Ваша команда eval
не предотвращает разбиение слов:
eval ${CMDS[$kpair]}
Вы хотите это:
eval "${CMDS[$kpair]}"
без кавычек, ваша команда произвольно нарезается на поля в пустом пространстве.Затем eval
объединяет части вместе, используя один пробел между ними, и оценивает полученный синтаксис.Разницу можно продемонстрировать на следующем примере:
$ cmd="awk '/foo/ { print \$1\" \"\$2 }'"
$ echo 'foo a' | eval $cmd
foo a
$ echo 'foo a' | eval "$cmd"
foo a
Мы можем просто использовать echo
, чтобы понять проблему:
$ echo $cmd
awk '/foo/ { print $1" "$2 }'
$ echo "$cmd"
awk '/foo/ { print $1" "$2 }'
Подстановка $cmd
и последующее словорасщепление выполняется независимо от любого синтаксиса оболочки, который содержит `cmd.Мы можем видеть такие фрагменты, как это:
$ for x in $cmd ; do echo "<$x>" ; done
<awk>
<'/foo/>
<{>
<print>
<$1">
<"$2>
<}'>
Когда мы выполняем eval $cmd
, вышеуказанные фрагменты генерируются и повторно комбинируются с помощью eval
и оцениваются.Излишне говорить, что вы не хотите, чтобы ваш командный синтаксис был нарезан и повторно объединен таким образом;кто знает, какого рода скрытая ошибка возникнет.Это может быть хорошо для команд, которые у вас сейчас есть, но как общий механизм диспетчеризации команд, он имеет недостатки.