1

I have made a simple backup program for my bin folder. It works. Code and resultant STDOUT below. Using rsync to copy from local ~/bin folder to a /media/username/code/bin folder. The code works fine when only one result from mount | grep media but I can not quite fathom how to advance it to letting me select from multiple results from the mount/grep. I suspect the for LINE below is lucky to work at all as I believe for is delimited by spaces, in shell scripting, but as there are no spaces in the results it then delimited on the \n ? I tried find /media and of course got a lot of results. Not the way to go I think. O_O

check_media () {
  FOUNDMEDIA=$(mount | awk -F' ' '/media/{print $3}')
  echo -e "foundmedia \n$FOUNDMEDIA"
  echo For Loop
  for LINE in $FOUNDMEDIA
  do
    echo $LINE
  done
  CHOSENMEDIA="${FOUNDMEDIA}/code/bin/"
  echo -e "\nchosenmedia \n$CHOSENMEDIA\n"
  exit
}
foundmedia 
/media/dee/D-5TB-ONE
/media/dee/DZ61

For Loop
/media/dee/D-5TB-ONE
/media/dee/DZ61

chosenmedia 
/media/dee/D-5TB-ONE
/media/dee/DZ61/code/bin/

You can see how I add the save path /code/bin to the found media but with multiple results I get a chosenmedia which cannot work. I would like to be able to choose the media to which I want to rsync my backup to, or restore from.

2
  • You should look into fzf and dmenu, they allow you to easily choose from a generated list, e.g.: CHOSENMEDIA=$(mount | awk ... | fzf)
    – Thor
    Commented Oct 17, 2022 at 12:18
  • will do, thanks
    – Dee
    Commented Oct 17, 2022 at 12:59

1 Answer 1

1

Assuming your mount points don't contain whitespace you can use a script like this:

#!/bin/bash

check_media() {
    local found=(_ $(mount | awk '/media/{print $3}'))
    local index chosen

    until [[ "$chosen" =~ ^[0-9]+$ ]] && [[ "${chosen:-0}" -ge 1 ]] && [[ "${chosen:-0}" -lt ${#found[@]} ]]
    do
        for ((index=1; index < "${#found[@]}"; index++))
        do
            printf '%2d) %s\n' $index "${found[$index]}" >&2
        done

        read -p "Choice (q=quit): " chosen || { echo; return 1; }
        [ "$chosen" == q ] && return 1
    done

    printf '%s\n' "${found[$chosen]}"
}

if chosen=$(check_media)
then
    printf 'Got: %s\n' "$chosen"
fi

However, if you are writing for bash the whole thing can be encapsulated in just a couple of lines, replacing check_media like this:

select chosen in $(mount | awk '/media/{print $3}')
do
    printf 'Got: %s\n' "$chosen"
    # rsync
    break
done
2
  • oh that succinct bit of code - thank you. Although I though it was a fail at first but after s/smbfs/media/ it worked. I came back here because I found a very wordy kludge using an array. i am too embarrassed to post it after seeing your half dozen lines. TYVM @roaima
    – Dee
    Commented Oct 17, 2022 at 12:17
  • Oh sorry. Guess what I was testing with...! I'll fix the answer for future reference Commented Oct 17, 2022 at 12:27

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.