6

example

#!/bin/bash

INSTALL_PATH="/usr/local"
BFGMINER_INSTALL_PATH="${INSTALL_PATH}/bfgminer"
BFGMINER_REPO="https://github.com/luke-jr/bfgminer.git"

list_last_ten_bfgminer_tags () {
    cd ${BFGMINER_INSTALL_PATH}
    git for-each-ref --format="%(refname)" --sort=-taggerdate --count=10 refs/tags | cut -c 6-
}

clone_bfgminer () {
    cd ${INSTALL_PATH}
    git clone ${BFGMINER_REPO} ${BFGMINER_INSTALL_PATH}
}

echo "select number to switch tag or n to continue"
select result in master $(list_last_ten_bfgminer_tags)
do

    # HOW DO I CHECK THE INDEX???????  <================================= QUESTION
    if [[ ${result} == [0-9] && ${result} < 11 && ${result} > 0 ]]
        then
            echo "switching to tag ${result}"
            cd ${BFGMINER_INSTALL_PATH}
            git checkout ${result}
    else
        echo "continue installing master"
    fi

    break
done

So if the user enters 1, the case statement checks for the match on the text, how can I match on 1 instead?

7
  • Related and very useful: stackoverflow.com/a/226724/1983854 Commented Mar 28, 2014 at 13:30
  • @fedorqui thanks, I have seen this before and is a great post, I'm looking to see if I can access the bash select array by index Commented Mar 28, 2014 at 13:33
  • I don't understand your question, if the value were returned how would you know which answer was selected? You typically want the value and not the index which is the whole convenience of select. Commented Mar 28, 2014 at 13:33
  • 1
    Please post some code indicating how you are populating the menu. It's difficult to suggest a solution without know the exact problem you are having. Commented Mar 28, 2014 at 13:34
  • @chepner updated with my code Commented Mar 28, 2014 at 13:39

3 Answers 3

15

Use the $REPLY variable

PS3="Select what you want>"
select answer in "aaa" "bbb" "ccc" "exit program"
do
case "$REPLY" in
    1) echo "1" ; break;;
    2) echo "2" ; break;;
    3) echo "3" ; break;;
    4) exit ;;
esac
done
Sign up to request clarification or add additional context in comments.

2 Comments

+1 This definitely answer their question but OP is doing it in a very non-idiomatic way to begin with so I advise against doing this, it's just not necessary.
@AdrianFrühwirth honestly, i'm readed only the title and the last scentence with the question. ;) So, youre probably right. ;)
6

You don't need to check which value is selected; you can simply use it. The only thing you do want to check against is master, which is simple to do.

select result in master $(list_last_ten_bfgminer_tags)
do
    if [[ $result = master ]]; then
        echo "continue installing master"
    elif [[ -z "$result" ]]; then
        continue
    else
        echo "switching to tag ${result}"
        cd ${BFGMINER_INSTALL_PATH}
        git checkout ${result}
    fi
    break
done

7 Comments

no I get this, but what I they fat finger and enter in 23, it's not an option, how do I handle this?
You don't; select handles it for you. If you type 23, and there is no option 23, select makes you enter another choice before it will enter the body. If there is a choice 23, well, how is your code suppose to distinguish between an intentional choice and a typo?
maybe I'm missing this, I'm testing the changes but it still ends if I select an option not on the menu
Sorry, I misinterpreted my own test. I'll fix the answer in a moment. Specifically, result will be set to the empty string if you make an invalid choice. (Adrian alluded to this, but deleted his comment, apparently.)
Thanks, that did it but I did need to move the break to inside the if and else
|
4

I am struggling to understand your question but here is some example code; the array could be dynamically populated which I guess is where you are coming from:

$ cat t.sh
#!/bin/bash

foo=(one two three four)

echo "Please select an option: "
select reply in "${foo[@]}"; do
        [ -n "${reply}" ] && break
done
echo "You selected: ${reply}"

.

$ ./t.sh
Please select an option:
1) one
2) two
3) three
4) four
#? 5
#? 100
#? 2
You selected: two

How is this insufficient?

Of course, you could also use read and build the functionality yourself if you want the output/logics to differ from what select offers.

7 Comments

updated my question with more code, does this change your answer?
Not really, I still don't understand why you want/need the index. Your values are git tags and you want to do something with those tags, how is the select index relevant? As I demonstrated the variable set by select will be empty if no answer was selected, so if you enter an invalid value or just press enter you would continue your workflow installing master. You don't need to manually check if $result is within range.
say the user enters in 30, there is no tag and I wanted to output a message, also if the user does not want to switch tags, I thought by validating with the index I could control the flow better. Also when I change to another repo, it might not have tags and or the tags will be named differently
If the use enters 30, select detects that is an invalid choice and prompts you again.
It doesn't matter if the tags will be named differently because you only need to check for the master case specifically and just use the result.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.