3

I am using a script to manage stuff on external dives. At the end I want to give the user the option to leave or dismount the drives. I'd like to add a timeout and use the second option (do nothing) if the user has not responded.

I am fairly new to Linux and the References I have found so far are way too cryptic for my current level of linux-ness. It seems the Reference writers assume everyone is already fluent in Linux. :)

How do I add a timeout to this or a better way of doing this with a timeout and default action?

note: "myDrives" is my own program to handle the closing of files etc and dismount

echo "Do you want to un-Mount the External Drives?"
echo ""
select yn in "yes" "no"; do
  case $yn in
    yes ) sudo myDrives --unmount; 
          break;;
    no ) break;;
  esac
done
kill -9 $PPID
3

Here's one way to do it, using the -t timeout option of the bash read builtin:

#!/bin/bash

while :
do
  read -t10 -p "Do you want to un-Mount the External Drives? (Y/N): "
  if [ $? -gt 128 ]; then
    echo "timed out waiting for user response"
    break
  fi

  case $REPLY in
  [yY]*)
    echo "do it"
    break
    ;;
  [nN]*)
    echo "don't do it"
    break
    ;;
  *) echo "Please enter Y or N"
     ;;
  esac
done

See help read from the bash prompt, or man bash.

  • Thanks, this is more simple for me to understand at my current level of Linux. But then I like simple anyway, always easier to read and understand some months later. – LinuxFerLife Jun 8 '17 at 17:59
1

Here's another way to do it:

#!/bin/bash

printf "%s\n" "Do you want to un-Mount the External Drives?" 
timeout --foreground 10 bash -c '
    select sel in "yes" "no"
    do
        echo "$REPLY"
        break
    done' | while read -r answer; do
        echo ">>Got from user: $answer"
        case "$answer" in
            "yes") echo "Unmounting stuff" ;;
        esac
done

Key points to note:

  • timeout requires an actual process, not shell command. Here we spawn bash shell as separate process and let it do the job of driving select.
  • printf is used outside of timeout to avoid sending its text via pipe
  • while read -r answer; do . . .done will operate if and only if it received something via pipe. Thus if the previous bash process timed-out , it won't run - there's your default action of not doing anything.
  • if the while loop received something via pipe, it will check whether it's the yes answer, otherwise - it will do nothing
  • Thanks, but I prefer the option SteelDriver gave. I do appreciate you taking the time to also describe what is happening. – LinuxFerLife Jun 8 '17 at 18:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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