0

I have the following script saved into a menu.sh file.

declare -a menu=("Option 1" "Option 2" "Option 3" "Option 4" "Option 5" "Option 6")
cur=0

draw_menu() {
    for i in "${menu[@]}"; do
        if [[ ${menu[$cur]} == $i ]]; then
            tput setaf 2; echo " > $i"; tput sgr0
        else
            echo "   $i";
        fi
    done
}

clear_menu()  {
    for i in "${menu[@]}"; do tput cuu1; done
    tput ed
}

# Draw initial Menu
draw_menu
while read -sn1 key; do # 1 char (not delimiter), silent
    # Check for enter/space
    if [[ "$key" == "" ]]; then break; fi

    # catch multi-char special key sequences
    read -sn1 -t 0.001 k1; read -sn1 -t 0.001 k2; read -sn1 -t 0.001 k3
    key+=${k1}${k2}${k3}

    case "$key" in
        # cursor up, left: previous item
        i|j|$'\e[A'|$'\e0A'|$'\e[D'|$'\e0D') ((cur > 0)) && ((cur--));;
        # cursor down, right: next item
        k|l|$'\e[B'|$'\e0B'|$'\e[C'|$'\e0C') ((cur < ${#menu[@]}-1)) && ((cur++));;
        # home: first item
        $'\e[1~'|$'\e0H'|$'\e[H')  cur=0;;
        # end: last item
        $'\e[4~'|$'\e0F'|$'\e[F') ((cur=${#menu[@]}-1));;
         # q, carriage return: quit
        q|''|$'\e')echo "Aborted." && exit;;
    esac
    # Redraw menu
    clear_menu
    draw_menu
done

echo "Selected item $cur: ${menu[$cur]}";

I now have a second main.sh where i call the menu.sh file like this: ./menu.sh (they are in the same directory). How can i get the output of the menu.sh from the main.sh? I can't get the echo to the standard output by piping or redirecting for some reason. Accessing it via $() also doesn't work. What am i doing wrong?

Thanks in advance for all helpt!

7
  • what do you mean by 'get the output'? are you trying to capture the menu.sh output into a variable? something else? fwiw, assuming the only contents of main.sh is ./menu.sh ... the script works for me, ie, running main.sh from the command line displays the menu in my window (aka stdout)
    – markp-fuso
    Commented Jan 24, 2022 at 22:00
  • 1
    Is any of the tput and key reading magic relevant, or can you remove that and still show the problem you're encountering (minimal reproducible example)? Commented Jan 24, 2022 at 22:30
  • @BenjaminW.I actually copied the code from here: bughunter2k.de/blog/cursor-controlled-selectmenu-in-bash. Commented Jan 24, 2022 at 23:06
  • 1
    val=$(./menu.sh) (obvously) redirects stdout into the ariable val hence the reason your stdout 'disappears' ("Duh, Mark!" ?); while there's probably a way to redirect 'some' of stdout to a variable, the addition of tput calls and specialized cursor codes is going to add more complexity to the mix; at this point the provided script is (somewhat) complex and (imo) detracts from the true issue which is ... ?? what ?? ... you want to access the last line of the displayed menu? at this point I'm not sure what it is you're trying to accomplish ....
    – markp-fuso
    Commented Jan 24, 2022 at 23:19
  • 1
    I'd suggest reviewing Hot to create a minimal, reproducible example and then come back and update the question; in particular reduce menu.sh to a minimum set of code that generates the desired output, then tell us what part of this output you want 'redirected' to main.sh; some idea of what you want to so with the redirected data would also help (eg, store in variable? store in array? something else)? once you get something working for the minimal case then you can proceed to figuring out how to apply to your actual code
    – markp-fuso
    Commented Jan 24, 2022 at 23:21

1 Answer 1

1

One approach would be to use another file to store the result.

  1. In your main.sh, come up with a temp file name. Supply this temp file name to menu.sh

  2. Add some handling in menu.sh to ensure that this file is supplied before going on. Change the result of menu.sh to write to the temp file

  3. Back in main.sh, read the results from the temp file. Then get rid of the file

So, here is main.sh

RESULTS_FILE=results.`date +%s`.txt
./menu.sh $RESULTS_FILE
RESULTS=`cat $RESULTS_FILE`
echo "Got results:"
echo $RESULTS
rm $RESULTS_FILE

And then here is how you'd modify menu.sh

At the top

if [ "$1" == "" ] ; then 
    exit "You need to supply a temp file path"
fi
RESULTS_FILE=$1

At the bottom of menu.sh, change the last line to write to the file:

echo "Selected item $cur: ${menu[$cur]}" > $RESULTS_FILE

1
  • Thank your for your help, worked like a charm Commented Jan 27, 2022 at 15:38

Not the answer you're looking for? Browse other questions tagged or ask your own question.