maciek2791 maciek2791 - 4 months ago 8
Linux Question

Assign into named variable within a shell function

I have typical issue with assign into variable select statement,
I've tried many options, but none of them work..

I have function which replace column name on upper(column name).

Upper=(Column1 Column2) # Array variable

upper_function()
{
query="$1"
for ((i=0;i<${#Upper[@]};i++))
do
query=$(echo "$query" | sed -e "s/\b"${Upper[$i]}"\b/UPPER(${NAME[$i]})/g")
done
SQLQUERY="$query"
}


Below I have SQL statement:

SQLQUERY="Select column1,column2 from table"


Now, I would like to change column1 and column2 to

upper(column1) and upper(column2).


So I run function:

upper_function "$SQLQUERY"


Solution above works fine, but the case is that instead of

SQLQUERY="$query"


I would like to make my function more automatic and assigning name of Select statement into variable eg like below:

$2="$query"


and then run function:

upper_function "$SQLQUERY" "SQLQUERY"


But it is not working and I have no idea why, how to assign that variable properly? Thanks

Answer

This is, at its core, BashFAQ #6.

printf -v can be used for indirect assignments in modern (3.1+) versions of bash:

Upper=( column1 column2 )  # Array variable

upper_function() {
  local colname query=$1 varname=$2
  for colname in "${Upper[@]}"; do
    query=$(echo "$query" | sed -e "s/\b"${colname}"\b/UPPER($colname})/g")
  done
  printf -v "$varname" %s "$query"
}

...thereafter:

upper_function "$SQLQUERY" SQLQUERY

On older shells, instead:

eval "$varname=\$query"

...note that you need to trust the value of $varname to not be malicious, as code injected into that variable will be run by the function. Thus, you would never want to use a filename, table name, or other potentially-attacker-controlled variable to name a variable assigned to in this way.