Linux - Newbie This Linux forum is for members that are new to Linux.
Just starting out and have a question?
If it is not in the man pages or the how-to's this is the place! |
Notices |
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
Are you new to LinuxQuestions.org? Visit the following links:
Site Howto |
Site FAQ |
Sitemap |
Register Now
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
|
 |
|
12-11-2009, 09:34 PM
|
#1
|
LQ Newbie
Registered: Dec 2009
Posts: 27
Rep:
|
BASH - How to access a variablized variable?
Greetings everone, I'm new here and need a bit of help.
I'm having an issue trying to pull the value out of a variable I have set. I have a loop that its variable is part of the name of a different variable. I can set it, but I cannot grab its value. My problem is, I don't know how to force BASH to treat the entire block of text as a single variable; it keeps breaking it into two. How can I make it treat it as one? Example -
Code:
STRING1=MyName
SOME_VALUE=Devon
STRING2_$STRING1_REST_OF_STRING=SOME_VALUE < this sets properly.
My problem is, how do I access it? If I try this -
echo $STRING2_${STRING1}_REST_OF_STRING, it treats is as two variables. If I print it out, I get basically
${STRING1}_REST_OF_STRING
with the $STRING2_ missing. I know it's doing it because it's splitting my variable into $STRING2_ as one variable (which is set to nothing) and ${STRING1}_REST_OF_STRING as a separate variable, which also is set to nothing.
If I try -
${STRING2_${STRING1}_REST_OF_STRING}
I get an error about bad substitution.
I'm assuming since I can set the "big" variable, there is some built-in that I can use to force it to treat it as one variable and not two separate varaibles, but what is it? Google has left me empty handed so far. I've tried single quotes, double quotes, I've even got it to set to another variable properly, but then it treats that variable as a literal, and I cannot get it to print out its value. For example -
Code:
NEW_STRING=`\$STRING_2${STRING1}_REST_OF_STRING`
It will print out the literal "$STRING_2MyName_REST_OF_STRING", but I can't get to the value I set it to, which is Devon.
Help, please!
Devon
Last edited by DevonB; 12-11-2009 at 09:35 PM.
|
|
|
12-11-2009, 09:44 PM
|
#2
|
LQ Guru
Registered: Dec 2006
Location: underground
Distribution: Slackware64
Posts: 7,594
|
Hopefully this will help you:
Code:
sasha@reactor:~$ STRING1=MyName
sasha@reactor:~$ SOME_VALUE=Devon
sasha@reactor:~$ newvar=$(eval echo \${STRING2_$STRING1_REST_OF_STRING=$SOME_VALUE})
sasha@reactor:~$ echo $newvar
Devon
sasha@reactor:~$
sasha@reactor:~$ eval echo \${STRING2_$STRING1_REST_OF_STRING}
Devon
sasha@reactor:~$
Sasha
Last edited by GrapefruiTgirl; 12-11-2009 at 09:46 PM.
|
|
1 members found this post helpful.
|
12-11-2009, 10:22 PM
|
#3
|
Senior Member
Registered: Aug 2006
Posts: 2,697
|
please, try to use arrays/associative arrays, now that newer bash supports them.
Code:
declare -a array
declare -A dict
STRING1=MyName
SOME_VALUE=Devon
array[0]=$SOME_VALUE
dict["STRING2_$STRING1_REST_OF_STRING"]=$SOME_VALUE
#print array value
echo ${array[0]}
#print associative array
echo ${dict[@]}
echo ${array["STRING2_$STRING1_REST_OF_STRING"]}
Last edited by ghostdog74; 12-11-2009 at 10:24 PM.
|
|
|
12-11-2009, 11:02 PM
|
#4
|
Senior Member
Registered: Oct 2005
Distribution: Gentoo, Slackware, LFS
Posts: 2,248
|
If you already have or you can install bash 4.0, use associative arrays as ghostdog74 also suggested. It will really simplify things.
However if you still want to know how, perhaps you can play around with the ${!VAR} feature of bash.
Code:
VAR=data
VARPTR=VAR
echo ${!VARPTR}
|
|
|
12-12-2009, 12:30 AM
|
#5
|
Senior Member
Registered: Aug 2006
Posts: 2,697
|
Quote:
Originally Posted by konsolebox
If you already have or you can install bash 4.0, use associative arrays as ghostdog74 also suggested. It will really simplify things.
However if you still want to know how, perhaps you can play around with the ${!VAR} feature of bash.
Code:
VAR=data
VARPTR=VAR
echo ${!VARPTR}
|
should be careful when using this. try this
Code:
$ VAR=data
$ VARPTR=VAR
$ VARPTR1=VARPTR
$ echo ${!VARPTR1}
VAR
what do you think ${!VARPTR1} should be?
|
|
|
12-14-2009, 03:39 AM
|
#6
|
Senior Member
Registered: Oct 2005
Distribution: Gentoo, Slackware, LFS
Posts: 2,248
|
hmmm.. my guess :-).. VAR also no? it's obvious why? .. to get data using VARPTR1.. we need to reparse it:
Code:
TEMP=${!VARPTR1}
echo "${!TEMP}"
or
Code:
eval echo \"\${!${!VARPTR1}}\"
-- edit --
and if i'm to use another variable pointer, i'll call it VARPTRPTR although in my projects i alwayse use *VAR like:
Code:
ARRAY=()
ARRAYVAR=ARRRAY
ARRAYVARVAR=ARRAYVAR
such things does not appear much in my codes though. i just gave an example.
Last edited by konsolebox; 12-14-2009 at 03:46 AM.
|
|
|
12-14-2009, 03:40 AM
|
#7
|
Senior Member
Registered: Aug 2006
Posts: 2,697
|
and VAR is "data" , right?
|
|
|
12-14-2009, 03:48 AM
|
#8
|
Senior Member
Registered: Oct 2005
Distribution: Gentoo, Slackware, LFS
Posts: 2,248
|
yup. ... i sort of don't get the point. they're just variables pointing to strings right? .. not really pointers.. only ${!PARAM} does the magic.
|
|
|
12-14-2009, 03:55 AM
|
#9
|
Senior Member
Registered: Aug 2006
Posts: 2,697
|
Quote:
Originally Posted by konsolebox
hmmm.. my guess :-).. VAR also no? it's obvious why? .. to get data using VARPTR1.. we need to reparse it:
|
that's where the problem lies. At run time, you won't know how many levels you are going to parse. the syntax "${!<param>}" somehow is not used like that in the context of references.
|
|
|
12-14-2009, 04:02 AM
|
#10
|
Senior Member
Registered: Oct 2005
Distribution: Gentoo, Slackware, LFS
Posts: 2,248
|
Well it's enough if you're after only 1 level of reference. I don't really mean we should consider the method. I just gave the example for the single level.. It's up for the OP what he'll do .. either he still consider the re-reference thing or use eval.. but as I said before it's also better if he just use the hashes. You'll usually have to decide what other method to use when you're after at least more than 2 levels. I don't do that in my codes.
|
|
|
12-14-2009, 09:19 AM
|
#11
|
LQ Guru
Registered: Dec 2006
Location: underground
Distribution: Slackware64
Posts: 7,594
|
OK, the OP hasn't been back since asking this question.. Rather than perpetuate the discussion of 'this way is better, that way is better', I think we should wait for the OP's return and see if he/she has any input about the methods above. We don't even know what OS or shell the OP is using.
Frankly though, I don't see what was so difficult or horrid about my first reply, nor why using arrays would be (any/much) better. And, much of the above ideas imply not only a Bash shell, but assume that the OP has a new Bash shell, or is willing to get one; we know where assuming can lead us
@ Ghostdog, respectfully: your shell scripting help has many times proven very helpful to myself and others, and I appreciate that -- you're knowledgeable in this area, no question -- but on this subject of arrays, I'm getting a little bit of mixed messages from you. In this thread, you're suggesting use of arrays, yet in this other thread of mine you suggest I avoid (extensive use of) arrays and/or switch languages if I need a lot of array-like constructs  so why the difference? Was it the desire for POSIX-ness, or for portability, that your suggestion in that other thread was different? FWIW I'm working on a solution to that other thread today -- an update later I hope.
Thanks for clarification  -- on with the show,
Sasha
Last edited by GrapefruiTgirl; 12-14-2009 at 09:21 AM.
|
|
|
12-14-2009, 09:45 AM
|
#12
|
Senior Member
Registered: Aug 2006
Posts: 2,697
|
Quote:
Originally Posted by GrapefruiTgirl
@ Ghostdog, respectfully: your shell scripting help has many times proven very helpful to myself and others, and I appreciate that -- you're knowledgeable in this area, no question -- but on this subject of arrays, I'm getting a little bit of mixed messages from you. In this thread, you're suggesting use of arrays, yet in this other thread of mine you suggest I avoid (extensive use of) arrays and/or switch languages if I need a lot of array-like constructs  so why the difference? Was it the desire for POSIX-ness, or for portability, that your suggestion in that other thread was different? FWIW I'm working on a solution to that other thread today -- an update later I hope.
|
you misunderstood what i am trying to say in that thread. You mentioned you are starting a project which makes use of arrays, and that you worry about problems of shells not supporting arrays. Instead of worrying about how if you use arrays in your script and being not able to work for other shells that don't support it, I suggested to you to use a different programming language than the shell, such as Python (or Perl if you like). Python/Perl data types (arrays, variables, dictionaries/hashes) have been pretty standard since olden times, so you can be 99% sure that if you write your code in newer version of language, it can be used in older ones (data types/structures).
whereas coming back to this thread, its a different problem. OP is trying to set a variable name using another variable, which essentially in programming terms, is equivalent to assigning values to arrays.
consider this
don't you think it cleaner to use arrays
Code:
declare -a array
i=0
array[$i]=2
now, whenever you need to call element 1's value, you just do array[0]. No need to invoke eval. Variables, after all, after just names for memory addresses, so are array indexes.
of course, if the OP's shell doesn't support arrays/assoc arrays, then too bad. use the eval method.
Last edited by ghostdog74; 12-14-2009 at 09:59 AM.
|
|
|
12-14-2009, 11:23 AM
|
#13
|
LQ Guru
Registered: Dec 2006
Location: underground
Distribution: Slackware64
Posts: 7,594
|
OK, gotcha -- thanks for that clarification. To our detriment, I had not been clear enough in that other thread though: I should have made it more clear that I am not "just starting" that project, but rather it's been ongoing for a long time, and just lately, I began considering making it more portable, but it already has made extensive use of arrays, so I'm looking at a "conversion" issue, rather than starting a fresh project in a portable way.
My apology for the lack of clarity there.
Kind regards,
Sasha
|
|
|
12-14-2009, 05:34 PM
|
#14
|
Senior Member
Registered: Aug 2006
Posts: 2,697
|
Ah, i see. If you are still going to continue writing in shell, there are some books that you can take reference to. eg "Beginning Portable shell scripting" etc. Or search on the internet for articles about that. But personally, i think it will be worthwhile to port your project to Python, (or Perl). Besides making use of their good data structures, there are vast amount of libraries you can use for your project without reinventing the wheel. anyway, its up to you.
|
|
|
12-14-2009, 05:44 PM
|
#15
|
LQ Guru
Registered: Aug 2004
Location: Sydney
Distribution: Rocky 9.x
Posts: 18,434
|
I can definitely confirm that arrays are one of the 3 basic data types (scalar, array, hash) in Perl & as he hinted, there's a huge library of pre-written modules avail at search.cpan.org.
Note that a lot of those are already in the std Perl install http://perldoc.perl.org/perlfaq3.htm...n-my-system%3F
|
|
|
All times are GMT -5. The time now is 09:51 AM.
|
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.
|
Latest Threads
LQ News
|
|