Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use double $ in echo [duplicate]

Tags:

linux

bash

shell

[sudhir.tataraju.WBLL0717E4418] ➤ cat test.sh

#!bin/bash

i=2

value2=abc

echo "`$value$i`"

Output:

[sudhir.tataraju.WBLL0717E4418] ➤ sh test.sh
test.sh: line 8: 2: command not found

Debug output:

[sudhir.tataraju.WBLL0717E4418] ➤ sh -x test.sh
+ i=2
+ value2=abc
++ 2
test.sh: line 8: 2: command not found
+ echo ''

How to get output abc without error?

like image 642
sudhir tataraju Avatar asked Dec 31 '17 11:12

sudhir tataraju


People also ask

How do you use double quotes in Echo?

To print a double quote, enclose it within single quotes or escape it with the backslash character. Display a line of text containing a single quote. To print a single quote, enclose it within double quotes or use the ANSI-C Quoting .

How do you double quotes in bash?

A double quote may be quoted within double quotes by preceding it with a backslash. If enabled, history expansion will be performed unless an ' ! ' appearing in double quotes is escaped using a backslash. The backslash preceding the ' !

How do you add a double quote to a string in a shell?

You can't use double quotation within another double quotation to assign any string value. If you want to print double quote in the output then you have to use the backslash (\) with the string.

What's the difference between a single quote and a double quote in bash?

Single quotes won't interpolate anything, but double quotes will. For example: variables, backticks, certain \ escapes, etc. Enclosing characters in single quotes ( ' ) preserves the literal value of each character within the quotes. A single quote may not occur between single quotes, even when preceded by a backslash.


2 Answers

What you are trying to do can be achieved much better with arrays.

values=( value1 value2 value3 "This is value 4" )
echo "${values[2]}"
values[2]="other_value"
echo "${values[2]}"

Variables can also be used as the index:

i=2
echo "${values[$i]}"

Arrays make looping over the values very easy:

#looping over values
for value in "${values[@]}"; do
    echo "$value"
done
#looping over indexes
for index in "${!values[@]}"; do
    echo "${values[$index]}"
done

If you don't consider sparse or associative arrays, you can also loop like this:

for (( index=0; index<${#values[@]}; index++ )); do
    echo "${values[index]}"
done

Arrays are the right structure for your task. They offer great functionality. For more information on arrays, see: wiki.bash-hackers.org/syntax/arrays and Bash Reference Manual.

like image 83
PesaThe Avatar answered Sep 19 '22 14:09

PesaThe


What you're asking for can be achieved in two ways (without antipatterns or eval).

  1. Use indirect expansion:

    The basic form of parameter expansion is ${parameter}. The value of parameter is substituted. [...] If the first character of parameter is an exclamation point (!), [...] it introduces a level of variable indirection. Bash uses the value of the variable formed from the rest of parameter as the name of the variable; this variable is then expanded and that value is used in the rest of the substitution, rather than the value of parameter itself. This is known as indirect expansion.

    So what you want is:

    #!/bin/bash
    
    i=2
    
    value2=abc
    
    # Have a variable that expands to the name of the variable you want
    myvar=value$i
    
    # Use indirect expansion
    echo "${!myvar}"
    
  2. Realize that your design is very bad, and use some proper structure instead: Bash handles arrays. See PesaThe's answer. That's definitely the recommended method in your case.


Don't use eval. Though it might look great, you need a good deal of practice of shell scripting before you understand all the problems with eval. And when you have enough experience with Bash, you'll realize that you very very rarely need eval.

like image 32
gniourf_gniourf Avatar answered Sep 17 '22 14:09

gniourf_gniourf