You are not logged in.

#1 2023-09-19 03:54:09

duyinthee
Member
Registered: 2015-06-14
Posts: 222
Website

[SOLVED] can I set variables by $var=$var in nested for loops?

I am trying to set variables by $var=$var in the following nested for loops.
It does not work. Is there anything I can do like that?

#!/bin/bash
aa="bb cc dd ee ff gg"
for i in $aa; do
    for ii in BBVAR CCVAR DDVAR EEVAR FFVAR GGVAR; do
        # I am trying to set variable like BBVAR=bb for example.
        $ii=$i
    done
done
echo "$BBVAR" # expecting "bb" here
echo "$CCVAR" # expecting "cc" here
echo "$DDVAR" # expecting "dd" here
echo "$EEVAR" # expecting "ee" here
echo "$FFVAR" # ecpecting "ff" here
echo "$GGVAR" # expecting "gg" here

Last edited by duyinthee (2023-09-21 08:28:27)

Offline

#2 2023-09-19 05:51:16

Awebb
Member
Registered: 2010-05-06
Posts: 6,350

Re: [SOLVED] can I set variables by $var=$var in nested for loops?

Like this?

var1="hold"
declare $var1="told"
echo $hold

Offline

#3 2023-09-19 06:11:19

bulletmark
Member
From: Brisbane, Australia
Registered: 2013-10-22
Posts: 659

Re: [SOLVED] can I set variables by $var=$var in nested for loops?

Do you really want explicit variables for those indexed values? Why not:

#!/bin/bash
aa="bb cc dd ee ff gg"

set -- $aa
echo $1  # outputs "bb"
echo $2  # outputs "cc"
echo $3  # outputs "dd"

Offline

#4 2023-09-19 06:21:08

Awebb
Member
Registered: 2010-05-06
Posts: 6,350

Re: [SOLVED] can I set variables by $var=$var in nested for loops?

I suspect it's not about $aa, but a general question about dynamically named variables.

Offline

#5 2023-09-19 08:36:50

duyinthee
Member
Registered: 2015-06-14
Posts: 222
Website

Re: [SOLVED] can I set variables by $var=$var in nested for loops?

let me paste here my solution for what I am trying. But I want to combine those if...else...fi parts and shorten.
That's why, I am considering for i in; do... done

#!/bin/bash

aa="bb cc dd ee ff gg"
num=1
for i in $aa; do
    # for ii in BBVAR CCVAR DDVAR EEVAR FFVAR GGVAR; do
    #     declare "$ii=$i"
    # done
    if [[ $((num)) -eq 1 ]]; then
        BBVAR=$i
        num=$((num+1))
        continue
    fi
    if [[ $((num)) -eq 2 ]]; then
        CCVAR=$i
        num=$((num+1))
        continue
    fi
    if [[ $((num)) -eq 3 ]]; then
        DDVAR=$i
        num=$((num+1))
        continue
    fi
    if [[ $((num)) -eq 4 ]]; then
        EEVAR=$i
        num=$((num+1))
        continue
    fi
    if [[ $((num)) -eq 5 ]]; then
        FFVAR=$i
        num=$((num+1))
        continue
    fi
    if [[ $((num)) -eq 6 ]]; then
        GGVAR=$i
        num=$((num+1))
        continue
    fi
done
echo "$BBVAR"
echo "$CCVAR"
echo "$DDVAR"
echo "$EEVAR"
echo "$FFVAR"
echo "$GGVAR"

What I really want is to set many variables based on a command's outputs.

Last edited by duyinthee (2023-09-19 08:50:31)

Offline

#6 2023-09-19 09:55:47

Awebb
Member
Registered: 2010-05-06
Posts: 6,350

Re: [SOLVED] can I set variables by $var=$var in nested for loops?

Have you tried the declare thing I posted?

EDIT: I also recommend having a look at "associative array" in bash, like https://linuxhint.com/associative_array_bash/

Last edited by Awebb (2023-09-19 09:56:42)

Offline

#7 2023-09-19 17:35:36

eda2z
Member
From: Woodstock, IL
Registered: 2015-04-21
Posts: 66

Re: [SOLVED] can I set variables by $var=$var in nested for loops?

Replacing:

$ii=$i

with:

eval "$ii=$i"

will assign a value to all of the xxVAR variables but they will all be assigned the value gg. You have nested loops and the eval statement will be executed 36 times. Each xxVAR variable will be assigned each of the aa values consecutively. The following would work:

#!/bin/bash

declare -A assArray=( [BBVAR]=bb
                      [CCVAR]=cc
                      [DDVAR]=dd
                      [EEVAR]=ee
                      [FFVAR]=ff
                      [GGVAR]=gg )

for val in "${!assArray[@]}"; do
   eval "$val=${assArray[$val]}"
done

echo "$BBVAR" # expecting "bb" here
echo "$CCVAR" # expecting "cc" here
echo "$DDVAR" # expecting "dd" here
echo "$EEVAR" # expecting "ee" here
echo "$FFVAR" # ecpecting "ff" here
echo "$GGVAR" # expecting "gg" here

Last edited by eda2z (2023-09-19 17:56:05)

Offline

#8 2023-09-21 08:12:03

duyinthee
Member
Registered: 2015-06-14
Posts: 222
Website

Re: [SOLVED] can I set variables by $var=$var in nested for loops?

Thanks you all for replies with suggestions. Yes, it works with "declare" and also "eval".
What I do now is this below;

#!/bin/bash

aa="bb cc dd ee ff gg"
IFS=' '
NUM=1
for i in $aa; do
    ii=$(echo "BB CC DD EE FF GG" | cut -d ' ' -f "$NUM")
    eval $i=$ii # here (declare $i=$ii) is also work
    NUM=$((NUM+1))
done

echo $bb
echo $cc
echo $dd
echo $ee
echo $ff
echo $gg

I don't know declare or eval is the right one here.

Offline

#9 2023-10-23 03:48:35

SpaceshipOperations
Member
Registered: 2019-06-24
Posts: 15

Re: [SOLVED] can I set variables by $var=$var in nested for loops?

Be extremely careful with `eval` because it allows arbitrary code execution, which is especially dangerous if your variables are taken from arbitrary input.

name=BBVAR
value=$(cat evil_file)
eval $name=$value
# Congratulations, your home directory was wiped clean
# The contents of "evil_file" were "bb; rm -rf -- ~/* ~/.*"

I suggest you stick with associative arrays, similar to eda2z's suggestion, which make things a tad easier and safer:

keys=(name age gender balance)

declare -A client
client[name]=Alice
client[age]=25
client[gender]=female
client[balance]=10000

for key in "${keys[@]}"; do
    echo key: "$key", value: "${client[$key]}"
done

# Or if you don't want a static key list, you can always do:

for key in "${!client[@]}"; do
    echo key: "$key", value: "${client[$key]}"
done

Outputs:

key: name, value: Alice
key: age, value: 25
key: gender, value: female
key: balance, value: 10000

If you absolutely have to reference variable names outside of associative arrays, Bash allows the so-called indirect expansion using the `${!var}` syntax, which expands to the value of the variable whose name is stored in `var`.

age=25
var=age
echo "name: ${var}, value: ${!var}"

Outputs:

name: age, value: 25

For assignment, I think the only (possibly) safe way would be something like this:

declare -- "$name=$value"

Observe that we used `--` to make it impossible for `$name=$value` to be interpreted as an option string in case `$name` starts with a hyphen, and more importantly, we quoted the whole thing to prevent Bash from splitting them into multiple arguments in case they contain any whitespace, which would result in buggy code at best and security exploits at worst.

Offline

Board footer

Powered by FluxBB