Пользовательский ввод с таймаутом

Я использую скрипт для управления внешними погружениями. В конце я хочу дать пользователю возможность покинуть или отключить диски. Я хотел бы добавить время ожидания и использовать второй вариант (ничего не делать), если пользователь не ответил.

Я довольно новичок в Linux, и ссылки, которые я нашел до сих пор, слишком загадочны для моего текущего уровня Linux. Кажется, авторы справочных материалов предполагают, что все уже свободно владеют Linux. :)

Как добавить тайм-аут к этому или лучший способ сделать это с тайм-аутом и действием по умолчанию?

примечание: «myDrives» - моя собственная программа для обработки закрытия файлов и т. Д. И размонтирования

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
задан 8 June 2017 в 18:53

3 ответа

Вот один из способов сделать это, используя опцию -t timeout встроенной команды bash read:

#!/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

См. help read в приглашении bash или man bash.

0
ответ дан 8 June 2017 в 18:53

Вот еще один способ сделать это:

#!/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

Ключевые примечания:

  • timeout требует фактического процесса, а не команды оболочки. Здесь мы порождаем bash shell как отдельный процесс и позволяем ему выполнять работу по вождению select.
  • printf используется за пределами timeout, чтобы избежать отправки его текста по каналу.
  • while read -r answer; do . . .done будет работать тогда и только тогда, когда получит что-то по каналу. Таким образом, если время ожидания предыдущего bash процесса истекло, оно не запустится - по умолчанию вы выполняете действие - ничего не делать.
  • если цикл while получил что-то по каналу, он проверит, является ли это ответом yes, в противном случае - он ничего не сделает
0
ответ дан 8 June 2017 в 18:53

Вы можете использовать переменную TMOUT, которая рассматривается с помощью select:

echo "Do you want to un-Mount the External Drives?"
TMOUT=10 # 10 seconds time-out
select yn in "yes" "no"; do
  case $yn in
    "yes" ) echo "unmount" ;;
    "no" ) echo "don't unmount" ;;
  esac
  break;
done
if [ -z "$yn" ] ; then
  echo "default action"
fi
1
ответ дан 23 June 2020 в 14:50

Другие вопросы по тегам:

Похожие вопросы: