0

Getting error while executing below in Unix: i want the 3rd line to get work... In ksh shell

while [ ${i} -le 3 ]
do
     var${i}="hello${i}"
     echo "${var}${i}"
     i=`expr ${i} + 1`
done

I want to get a output like below,

hello1
hello2
  • 1
    Which shell do you want to use? Do you want a POSIX compliant solution, or bash or zsh or something else? – Eric Renouf Sep 13 '17 at 11:38
  • ... what error? – RomanPerekhrest Sep 13 '17 at 11:40
  • I want in Ksh shell – Gvtha Sep 13 '17 at 11:45
  • 2
    So much easier to use an array than to use dynamic variable names. – glenn jackman Sep 13 '17 at 13:50
  • Which ksh shell? ksh88, ksh93, pdksh or mksh? What does echo $KSH_VERSION display? – Kusalananda Sep 14 '17 at 6:16
3

In POSIX sh, you'd need eval to use variables with dynamic names.

i=0
while [ "$i" -le 3 ]
do
   eval '
     var'"$i"'="hello${i}"
     echo "var$i = ${var'"$i"'}"
   '
   i=$((i+1))
done
echo "${var1}"

When using eval, it's critical to make sure that only the variables that need to be expanded are expanded in the argument passed to eval (and that their value be sanitized (here we know they are safe sequences of decimal digits)).

Above only two of the $i's are expanded. To do that, we get out of the single (strong) quotes and insert the $i inside double quotes: eval '...'"$i"'...'.

Because it's so hard to get the quoting right (and it's dangerous if you don't), it's better to limit the use of eval as much as possible. Ideally only to transfer the content of the dynamic variable to a static one and/or back like:

i=0
while [ "$i" -le 3 ]
do
   var=hello$i # $var with static name
   eval "var$i=\$var" # transfer into variable with dynamic name

   echo "var$i = $var" # use var with static name instead of dynamic one
                       # everywhere else (for which we don't need eval)

   i=$((i+1))
done
echo "${var2}"

In ksh/zsh/bash/yash, you may want to use arrays instead (or associative arrays in ksh93, zsh or recent versions of bash). Note that ksh/bash array indices start at 0 and arrays are sparse (more like associative arrays with keys limited to positive integers) while in all other shells (including zsh and yash on the Bourne-like front), indices start at 1 and arrays are normal arrays.

In ksh/bash/zsh -o ksharrays:

unset -v var
i=0; while [ "$i" -le 3 ]; do
  var[i]=hello$i
  echo "var[$i]=${var[i]}"
  i=$((i+1))
done
echo "${var[1]}"

Or using another ((...)) extension of the POSIX sh syntax common to ksh/zsh/bash:

unset -v var
i=0; while ((i <= 3)); do
  var[i]=hello$i
  echo "var[$i]=${var[i]}"
  ((++i))
done
echo "${var[2]}"

Or with ksh93, bash, zsh -o ksharrays:

unset -v var
for ((i = 0; i <= 3; i++)); do
  var[i]=hello$i
  echo "var[$i]=${var[i]}"
done
echo "${var[3]}"
0

That's much easier with a for loop:

for i in 1 2 3; do
  echo var$i\ =\ hello$i
done

Tested in bash.

  • Actually the main idea is i want assign value to the variable instead of just displaying – Gvtha Sep 13 '17 at 11:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.