Results 1 to 9 of 9

Thread: Bash question: piecing together variables

  1. #1
    Join Date
    Aug 2009
    Beans
    3

    Question Bash question: piecing together variables

    I am completely new to both linux, ubuntu, and BASH. I'm trying to create a simple program and was doing okay until the past 4 hours. For the life of me I can't find a solution...

    I'm trying to refer to a variable list in a loop. My program starts by asking for a list of words:

    Code:
    #!/bin/bash 
    
    WDNUM=0
    WORKAROUND=1
    until [ $WORKAROUND = 0 ]; do
    let WDNUM+=1
    echo "Enter word #"$WDNUM", or type 0:"
    read WORKAROUND
    export WD$WDNUM=$WORKAROUND
    done
    once I'm done entering a list of words, I'd like to echo the list I've typed. This is what I tried:

    Code:
    NOTIFY=1
    WDPROCESS=1
    until [ $NOTIFY = 0 ]; do
    echo WD$WDPROCESS
    WORD=$WD2
    NOTIFY=$WORD
    let WDPROCESS+=1
    done
    
    exit
    the idea behind the line [echo WD$WDPROCESS] is that the first iteration would be [echo WD1], then [echo WD2] etc. but instead of treating the WD$WDPROCESS as a single variable, it treats it as the value of $WDPROCESS concatenated to the characters WD.

    So when I run it, this is what I get:
    Enter word #1, or type 0:
    one
    Enter word #2, or type 0:
    0
    WD1


    Where "WD1" is output, I want to get "one."

    Could somebody tell me how to declare the string as a single variable? Eventually I am going to try to replace the echo with a function, where I would have the same problem.

    A similar issue I had was trying to piece variables together to assign new variables like so:
    a=one
    b=TWO
    c=three
    d=FOUR
    $a$b=$c$d
    #where
    $a$b=$c$d is equivalent to oneTWO=threeFOUR

    Obviously I don't know what I'm doing. Any help appreciated.

  2. #2
    Join Date
    Dec 2008
    Location
    Kennewick, Washington
    Beans
    168
    Distro
    Ubuntu 10.04 Lucid Lynx

    Re: Bash question: piecing together variables

    which segment of code is your script???
    Avoid the Gates of Hell. Use Linux.

  3. #3
    Join Date
    Dec 2006
    Beans
    1,133
    Distro
    Ubuntu 10.04 Lucid Lynx

    Re: Bash question: piecing together variables

    I'm not really sure what you're trying to do, but perhaps search for "indirection" in the bash man page and see it that helps.
    There are no dumb questions, just dumb answers.

  4. #4
    Join Date
    Feb 2007
    Location
    Romania
    Beans
    Hidden!

  5. #5
    Join Date
    Aug 2006
    Location
    Madrid, Spain
    Beans
    299
    Distro
    Ubuntu 9.04 Jaunty Jackalope

    Re: Bash question: piecing together variables

    You need to use indirect references: instead of "echo WD$WDPROCESS", you need to use "eval echo \$WD$WDPROCESS". Note the escaped $ for the final expansion: the first (pre-eval) expansion substs WDPROCESS, then the shell executes "eval echo \$WD1", which is evaluated to "echo $WD1", which prints "one".
    May the Source be with you.

  6. #6
    Join Date
    Oct 2007
    Location
    Fort Collins, CO, USA
    Beans
    480
    Distro
    Ubuntu 9.04 Jaunty Jackalope

    Re: Bash question: piecing together variables

    You need to use the eval builtin to do indirect variable assignment.
    But you can use either eval or ${!VAR} for reading indirect variable values.
    Here are examples of assigning to and reading from an indirect variable
    and an array element.
    Code:
    N=3
    VALUE=three
    NAME=WD$N
    eval $NAME="$VALUE"
    echo $NAME
    echo "${!NAME}"
    A[$N]=$VALUE
    echo "${A[$N]}"
    There are more flexible ways to loop over the elements of an array or of a set of variable names with a common prefix.
    You can get a list of array index values with ${!A[@]}.
    You can get a list variable names matching a prefix with ${!prefix@}.
    Code:
    for INDEX in ${!A[@]}; do echo $INDEX ${A[$INDEX]};done
    for NAME in ${!WD@}; do echo $NAME ${!NAME};done
    Last edited by stroyan; August 3rd, 2009 at 03:16 AM. Reason: Fix typo, missing $

  7. #7
    Join Date
    Aug 2009
    Beans
    3

    Re: Bash question: piecing together variables

    Wow, thanks everyone. I never expected so many replies so quickly. Sorry if my question was confusing, I only decided to ask after it had gotten to 3am.

    I used the eval with \ to accomplish my goal. I'm sure my program is not very elegant, but it now works for my design. The finished code follows:

    Code:
    #!/bin/bash 
    
    WDNUM=0
    WORKAROUND=1
    until [ $WORKAROUND = 0 ]; do
    let WDNUM+=1
    echo "Enter word #"$WDNUM", or type \"0\" to finish:"
    read WORKAROUND
    export WD$WDNUM=$WORKAROUND
    done
    
    function repeater {
    echo $1
    }
    
    echo ""; echo "###################### START ######################"
    
    CHECK=1
    until [ $CHECK = 0 ]; do
    eval repeater \$WD$WDPROCESS
    let WDPROCESS+=1
    eval CHECK=\$WD$WDPROCESS
    done
    
    echo ""; echo "######################  END  ######################"
    exit
    This is an example of me using it:

    Enter word #1, or type "0" to finish:
    Hello
    Enter word #2, or type "0" to finish:
    Ubuntu
    Enter word #3, or type "0" to finish:
    Forum
    Enter word #4, or type "0" to finish:
    0

    ###################### START ######################

    Hello
    Ubuntu
    Forum

    ###################### END ######################
    I have yet to learn the code in the other replies, which I'll do now. Thank you all so much.

    BTW, could anybody hint how I could place the "read" inline with the "Enter word..."?

    And/or how do I accept read input with spaces?
    This is what happens now:
    Enter word #1, or type "0" to finish:
    hello world
    tester.sh: line 5: [: too many arguments

  8. #8
    Join Date
    Oct 2007
    Location
    Fort Collins, CO, USA
    Beans
    480
    Distro
    Ubuntu 9.04 Jaunty Jackalope

    Re: Bash question: piecing together variables

    You can use read -p to specify a prompt string instead of using echo.
    You will need to add quoting around several instances of $VAR to handle spaces.
    Here is a diff of the changes you would make to use read -p and more quoting.
    Code:
    --- t.sh	2009-08-02 20:22:13.000000000 -0600
    +++ t2.sh	2009-08-02 20:29:39.000000000 -0600
    @@ -2,11 +2,10 @@
     
     WDNUM=0
     WORKAROUND=1
    -until [ $WORKAROUND = 0 ]; do
    +until [ "$WORKAROUND" = 0 ]; do
     let WDNUM+=1
    -echo "Enter word #"$WDNUM", or type \"0\" to finish:"
    -read WORKAROUND
    -export WD$WDNUM=$WORKAROUND
    +read -p "Enter word #$WDNUM, or type \"0\" to finish:" WORKAROUND
    +export WD$WDNUM="$WORKAROUND"
     done
     
     function repeater {
    @@ -16,8 +15,8 @@
     echo ""; echo "###################### START ######################"
     
     CHECK=1
    -until [ $CHECK = 0 ]; do
    -eval repeater \$WD$WDPROCESS
    +until [ "$CHECK" = 0 ]; do
    +eval repeater \"\$WD$WDPROCESS\"
     let WDPROCESS+=1
     eval CHECK=\$WD$WDPROCESS
     done

  9. #9
    Join Date
    Aug 2009
    Beans
    3

    Re: Bash question: piecing together variables

    Thank you Stroyan, that worked perfectly. The diff was a very informative way of showing me. LOL, I had to look up what diff meant before I could even start.

    All my questions have been satisfied, and my cheesy little program is exactly how I wanted it. This is so much fun! Thanks to all for putting up with someone with two days of programming experience.

    Finally I get to start work on the actual function.

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •