Search code examples
bashfunctionterminalaliasdebian-jessie

how to execute a bash alias or script were the output string is an already declared variable


first post :)

looked and researched for an answer for this challenge for days. I don't know what I'm missing. probably to close to it to see :) anyway, on with the challenge. below is a small piece of my .bashrc file. what I'm attempting to do is use an alias (bookmark bmp) to bookmark my current path (got this part working) and later recall all the bookmarks (with lsbmp) in a list form like ls does. I would use pushd / popd but I wish to be in control of which path I use as well as the order in which I use it.

I go for functionality first and cosmetics later (as you'll notice in the below code). you will also notice several commented out line for were I attempted different options (please forgive the mess). I pasted the output below the code. the outputted string "echo bmp1" is what should be ran not echoed. that's were I was stopped.

one last thing, if you can offer any suggestions to make this any better or add additional options, I'm open to that as well.

thank you in advance for any assistance you give or offer.

############################################
# bookmark section:
# list current bookmarked paths
function lsbmpvar {
  if [ -z "$bmpcounter" ]
  then
    bmpcounter=0
    bmp=""
    echo "bmpcounter is empty"
  else
    for bmpcount in $bmpcounter
    do
      bm="$"
      bm+="bmp"$bmpcount""
      bm1="echo "
      echo "${VAR1:="$bm1$bm"}"    # <--- printing out what I want to execute / run
      (( bmpcount++ ))
# commented out other items attempted below:
#    echo $bmpcounter
#      bm+="$("bmp"$bmpcount"")"
#      echo "$(bm)"
#      eval $bm
#      echo "$bm1$bm"
#      echo `$VAR1`
#      bbm=($(bm))
#      echo $bbm
#      echo "$bmp$bmpcount"
#      echo $(echo "bmp"$bmpcount"")
#      echo "$bmp"$bmpcount""
    done
  fi
}
alias lsbmp=lsbmpvar


# bookmark currrent path for later recall
function bookmarkpathvar {
  if [ -z "$1" ]
  then
    echo "# Usage:
# $ bookmarkpath bmp
# $ lsbmp to list all bookmarkpath
# already used bookmarkpath are"
    lsbmp
  else
    lsbmp
#    export $1=`pwd`;
    let "bmpcounter++"
    export $1$bmpcounter=`pwd`;
  fi
}
alias bookmarkpath=bookmarkpathvar
############################################

output

john@debian1:~$ bookmarkpath bmp
bmpcounter is empty
john@debian1:~$ cd 0_test/
john@debian1:~/0_test$ bookmarkpath bmp
echo $bmp1
john@debian1:~/0_test$ lsbmp
echo $bmp1
john@debian1:~/0_test$ echo $bmp0

john@debian1:~/0_test$ echo $bmp1
/home/john
john@debian1:~/0_test$ echo $bmp2
/home/john/0_test
john@debian1:~/0_test$

UPDATE BELOW (AS OF 20170615 0117)

ilkkachu (from comment below), thank you for your help.

answering your questions and statements in order (and numbered):

  1. it looks odd because it's an alias (is a small piece of my .bashrc file) and is meant to be ran in a command line environment (gnome-terminal in my case). I will see if I can remove the word script from the question so that it is not confusing (although your post could be used in a script).

  2. what I'm attempting to do is use an alias (bookmark bmp) to bookmark my current path and later recall all the bookmarks (with lsbmp) in a list form like ls does (and cd (with cdbmp) into them as well).

  3. and 4. your right about the -z test and the for loop. I really didn't know how to approach the challenge and due to recent surgery and pain meds I wasn't using full brain power. after your post, I realize that and reduced meds so my brain power is higher :) moral of the story is don't med and code haha

  4. yes an array will and does work nicely (thanks to you). I have to admit, I wouldn't have went the array route without your post and encouragement. thank you for that. I will be adding this experience and skill to my rolodex.

  5. "alias lsbmp=lsbmpvar" this alias is used in a command line environment (gnome-terminal). so the alias part is necessary for calling the function.

  6. you suspected correctly. please forgive me for the alias/script confusion. I also should have commented the code better. I will from now on.

I took your simple, concise, and eloquent code (with a few minor adjustments) and added it to my .bashrc file. it works beautifully! I have attached the finished code and output below my originally posted question in case anyone else would like a copy.

thanks again and have a fantastic day!

UPDATED AND FINAL CODE

# list current bookmarked paths
bmp=()
lsbmpvar() {
    if [ "${#bmp[@]}" = 0 ] ; then
        echo bmp is currently empty
    else
        i=0
        for x in "${bmp[@]}" ; do 
            echo "bmp$i: $x"
            let i++
        done
    fi
}
bmpadd() {
    bmp+=( $(pwd) )
    lsbmpvar
}
alias lsbmp=lsbmpvar
alias bmp=bmpadd


# bookmark currrent path for later recall
bookmarkpathvar() {
  if [ -z "$1" ]
  then
    echo "# Usage:
# $ bookmarkpath bmp (to add a bmp#)
# $ lsbmp (to list all bookmarked paths)
# $ cdbmp number (cdbmp 0) to move to that path (bmp0)
# current bookmarked paths are:"
    lsbmpvar
  else
    echo "# current path ( $(pwd) ) is now bookmarked to bmp"${#bmp[@]}"
# current bookmarked paths are:"
    bmpadd
  fi
}
alias bookmarkpath=bookmarkpathvar


cd_to_bmp() {
  if [ -z "$1" ]
  then
    echo "# Usage:
# $ cdbmp 0
# $ cdbmp number (cdbmp 0) to move to that path (bmp0)
# current bookmarked paths are:"
    lsbmpvar
  else
    echo "# moving to bmp$1 now"
    lsbmpvar
    cd ${bmp[$1]}
  fi
}
alias cdbmp=cd_to_bmp

OUTPUT:

john@debian1:~$ bookmarkpath    
# Usage:    
# $ bookmarkpath bmp (to add a bmp#)    
# $ lsbmp (to list all bookmarked paths)    
# $ cdbmp number (cdbmp 0) to move to that path (bmp0)    
# current bookmarked paths are:    
bmp is currently empty    
john@debian1:~$ bookmarkpath bmp    
# current path ( /home/john ) is now bookmarked to bmp0    
# current bookmarked paths are:    
bmp0: /home/john    
john@debian1:~$ cd 0_test/    
john@debian1:~/0_test$ bookmarkpath bmp    
# current path ( /home/john/0_test ) is now bookmarked to bmp1    
# current bookmarked paths are:    
bmp0: /home/john    
bmp1: /home/john/0_test    
john@debian1:~/0_test$ lsbmp    
bmp0: /home/john    
bmp1: /home/john/0_test    
john@debian1:~/0_test$ cd ${bmp[0]}    
john@debian1:~$ pwd    
/home/john    
john@debian1:~$ cdbmp 1    
# moving to bmp1 now    
# current bookmarked paths are:    
bmp0: /home/john    
bmp1: /home/john/0_test    
john@debian1:~/0_test$ bookmarkpath    
# Usage:    
# $ bookmarkpath bmp (to add a bmp#)    
# $ lsbmp (to list all bookmarked paths)    
# $ cdbmp number (cdbmp 0) to move to that path (bmp0)    
# current bookmarked paths are:    
bmp0: /home/john    
bmp1: /home/john/0_test    
john@debian1:~/0_test$     

Enjoy!


Solution

  • Ok, that script looks somewhat odd, and reading it, I'm not even sure what it is you're trying to do. Here are some thoughts, however.

    if [ -z "$bmpcounter" ]; then
        bmpcounter=0
    

    You do realize that -z doesn't test the following word against a numeric zero, but checks if it's the empty string? The assignment there makes bmpcounter non-empty.

    for bmpcount in $bmpcounter
    

    for loops over the words listed, in this case the words that come out when $bmpcounter is split. You're only setting bmpcounter in the above assignment to zero, and later with let "bmpcounter++", so it's only ever going to contain one word: a number. Incrementing bmpcount at the end of the loop doesn't do anything, there's still only going to be one iteration of the loop. Maybe you wanted to use a while loop instead?

    export $1$bmpcounter=`pwd`;
    

    This looks like you really want to use arrays

    bmp=(foo bar)         # initialize to contain two items
    bmp+=(quux)           # append a third
    for x in "${bmp[@]}" ; do   # loop over all items of the array
        something "$x"
    done
    echo "${bmp[0]}"      # access item at index zero
    

    I'm not even sure what you're trying to do with bm1 and bm and why go all the trouble of using those two, when you could use echo "echo bmp$bmpcounter" (or something like that).

    alias lsbmp=lsbmpvar
    

    This doesn't seem very useful. Why not just name the function lsbmp to begin with?


    What I suspect you want is something like this:

    bmp=()
    lsbmp() {
        if [ "${#bmp[@]}" = 0 ] ; then
            echo bmp is empty
        else
            i=0
            for x in "${bmp[@]}" ; do 
                echo "$i: $x"
                let i++
            done
        fi
    }
    bmpadd() {
        lsbmp
        bmp+=( $(pwd) )
    }