Хорошо знать, что есть проблемы с eval
( этим и этим ) и echo
( здесь ). Вы должны избегать eval
, это легко злоупотреблять.
Даже если эти команды абсолютно безопасны в ваших конкретных случаях, я советую вам отказаться eval
. Ваш код действительно слишком сложен из-за этого.
Ваш первый пример становится намного чище с массивами. Это работает в GNU bash 4.4.12 в моем Debian:
# preparing variables unset -v list s s1 s2 declare -a list=( foo 'X Y' bar baz ) declare -a s declare -A s1=( [foo]='FOO 1' [bar]='BAR 2' [baz]='BAZ beep; eject /dev/sr0' ) declare -A s2=( [foo]='oof oof' [bar]='rab rab' [baz]='zab zab' [X Y]='9') # your code rewritten, we don't even need a counter for j in "$" do s+=( "$" "$" ) done # checking contents of s printf '%s\n' "$"
Подсказка: исследование «индексированных массивов», «ассоциативных массивов» и их использование в bash
.
Обратите внимание, что элемент с пробелом ( X Y
) не является чем-то особенным для меня; но это сломало бы ваш код. Я также могу иметь BAZ beep; eject /dev/sr0
в моем s1
; Смею вас установить s1baz='BAZ beep; eject /dev/sr0'
, иметь baz
в своем list
массиве, выполнить ваш код и посмотреть, что произойдет. Это то, на что eval
способен. Теперь представьте, что я поставил rm -rf ~/
вместо eject …
.
Второй пример может быть значительно упрощен как:
sed -i "17i$sed17line" "$file"
Похоже, у вас есть некоторый уклон в сторону eval
+, echo
так как вы создали хитрое устройство, которое использует их дважды, когда ничего не нужно. Возможно, это потому, что ваши переменные не всегда расширяются до значений, когда вы этого хотите; если это так, исследуйте разницу между одинарными ( '
) и двойными кавычками ( "
) в bash
.
Слава за то, что сомневался и задавал вопрос.