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.

Dee
  • 33
  • 4

1 Answers1

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
roaima
  • 107,089
  • 14
  • 139
  • 261
  • 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 Oct 17 '22 at 12:17
  • Oh sorry. Guess what I was testing with...! I'll fix the answer for future reference – roaima Oct 17 '22 at 12:27