{
"$type": "site.standard.document",
"canonicalUrl": "https://rednafi.com/misc/dynamic-shell-variables/",
"description": "Learn variable indirection in Bash with ${!var} syntax. Build context-aware configs, function dispatch, and dynamic variable name resolution.",
"path": "/misc/dynamic-shell-variables/",
"publishedAt": "2025-01-11T00:00:00.000Z",
"site": "at://did:plc:fgtm2c26vfcj74rfmeggbyqj/site.standard.publication/3mnl6f7ob462z",
"tags": [
"Shell",
"Unix",
"TIL",
"CLI"
],
"textContent": "I came across a weird shell syntax today - dynamic shell variables. It lets you dynamically\nconstruct and access variable names in Bash scripts, which I haven't encountered in any of\nthe mainstream languages I juggle for work.\n\nIn an actual programming language, you'd usually use a hashmap to achieve the same effect,\nbut directly templating variable names is a quirky shell feature that sometimes comes in\nhandy.\n\nA primer\n\nDynamic shell variables allow shell scripts to define and access variables based on runtime\nconditions. Variable indirection (${!var} syntax) lets you reference the value of a\nvariable through another variable. This can be useful for managing environment-specific\nconfigurations and function dispatch mechanisms.\n\nHere's an example:\n\nHere, ${!var} resolves to the value of the variable config_path because var contains\nits name. This allows you to dynamically decide which variable to reference at runtime.\n\nContext-aware environment management\n\nA more practical use of dynamic shell variables is managing environment-specific\nconfigurations. This is particularly handy in scenarios where you have multiple environments\nlike staging and prod, each with its own unique configuration settings.\n\nRun the script with an environment as the argument:\n\nOutput for env=\"staging\":\n\nBy passing the environment as an argument, you can switch between environments without\nduplicating configuration logic.\n\nOne gotcha to be aware of is that appending text directly to the ${!VAR} syntax (e.g.,\n${!env}_URL) doesn't produce the intended results. Instead of resolving staging_URL,\nthis line will print only _URL:\n\nOutput:\n\nThis happens because ${!VAR} only resolves the value of VAR and doesn't support direct\nconcatenation. To avoid this, construct the full variable name (URL=\"${env}_URL\") before\nusing ${!VAR} for indirect expansion. This ensures the correct variable is accessed.\n\nFunction dispatch\n\nAnother neat use case for dynamic variables is function dispatch - calling the appropriate\nfunction based on runtime conditions. This technique can be used to simplify scripts that\nneed to handle multiple services or operations.\n\nRun the script with service and operation as arguments:\n\nThis returns:\n\nSimilarly, running ./script.sh db status prints:\n\nTemporary file handling\n\nDynamic variables can also help manage temporary files or logs in scripts that process\nmultiple datasets. By dynamically generating variable names, you can track temporary file\npaths for each dataset without conflicts.\n\nRunning this prints the following:\n\nHere, each dataset gets a unique temporary file, managed dynamically by the script. It\neliminates the need for manually creating and tracking file names.\n\nThis works, but like everything else in shell scripts, it can quickly turn into a hairball\nif we're not careful. While the syntax is nifty, I find it a bit hard to read at times!",
"title": "Dynamic shell variables"
}