TGViewer
BashTex | Linux BashTex | Linux @bash_tex · 2.51K subscribers
Post #390 1.09K
Использование printf -v для динамического формирования переменных

Бывает, что нужно создавать или заполнять переменные с динамическими именами: item_1, item_2, user_alice и т.д. Вместо eval попробуем использовать встроенный printf -v, который позволяет записать форматированный строковый результат прямо в переменную по имени.

Почему printf -v лучше, чем eval?

безопаснее (без спаивания и выполнения произвольного кода),
дает форматирование (числа, нули, float),
удобно в функциях (можно создавать глобальные переменные через declare -g).


▪️ Базовый пример: простая запись


name="user_alice"
printf -v "$name" "%s" "id=42"
echo "$user_alice"

id=42


Здесь мы записали строку в переменную user_alice без eval.

▪️ Нумерация с форматированием (zero-padding)


for i in {1..5}; do
printf -v "item_%03d" "$i" "val_$i"
done

# показать созданные переменные
for i in {1..5}; do
var="item_$(printf '%03d' "$i")"
echo "$var = ${!var}"
done

item_001 = val_1
item_002 = val_2


printf -v "item_%03d" "$i" "val" - формат имени и значение удобно комбинировать.

▪️ Создаем набор конфигов из CSV (пример)


while IFS=, read -r key value; do
# нормализовать имя (латиница, цифры, _)
safe_key=$(echo "$key" | tr -c '[:alnum:]_' '_')
printf -v "cfg_%s" "$safe_key" "%s" "$value"
done <<'CSV'
db.host,localhost
db.port,5432
feature.enable,true
CSV

echo "Host: $cfg_db_host"
echo "Port: $cfg_db_port"
echo "Feature: $cfg_feature_enable"


▪️ Инспекция созданных переменных


# показать все переменные с префиксом cfg_
for v in ${!cfg_*}; do
echo "$v = ${!v}"
done


(indirect expansion) позволяет получить значение переменной по имени.

▪️ Комбинация с declare -n (nameref)


printf -v "user_alice" "%s" "alice@bashtex.com"
ref_var="user_alice"
declare -n userref="$ref_var"
echo "Email via nameref: $userref"


declare -n дает ссылку на переменную, это удобнее, чем постоянно подставлять ${!name}.

▪️ Как избежать проблем с именами переменных. Переменная должна соответствовать правилам имени в bash. Можно валидировать:


sanitize() {
printf '%s' "$1" | sed 's/[^a-zA-Z0-9_]/_/g'
}

raw="user-name@host"
safe=$(sanitize "$raw")
printf -v "$safe" "%s" "value"


Если допустить в имени пробелы или символы ; - printf -v либо даст ошибку, либо поведет себя непредсказуемо.

BashTex 📱 #bash #utils
  • 👍 6
More from @bash_tex
  1. Oct 9, 2026BashTex 📱 #мем
  2. Oct 8, 2026Bridge FDB - как Linux bridge узнаёт, где находится MAC Linux bridge не знает заранее, за…
  3. Oct 7, 2026/dev/tcp - сетевое соединение средствами Bash В Bash есть малоизвестная возможность работа…
  4. Oct 6, 2026Ephemeral ports - почему заканчиваются исходящие TCP-порты Когда приложение устанавливает…
  5. Oct 5, 2026name_to_handle_at() - как получить файловый объект без обычного пути В Linux обычно обраща…
  6. Oct 2, 2026madvise() - как процесс подсказывает ядру, как он собирается использовать память Когда про…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →