用户输入超时


3

我正在使用脚本来管理外部潜水的东西。最后,我想为用户提供离开或卸下驱动器的选项。如果用户未响应,我想添加一个超时并使用第二个选项(不执行任何操作)。

我对Linux还是相当陌生,到目前为止,对于我目前的Linux-ness级别,我发现的参考文献太含糊了。参考作者似乎认为每个人都已经精通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

您可以简单地使用换行而不是第二回声\ n,还需要输入验证,如果用户输入y,n或诸如“ kjhdfklahs”之类的东西会发生什么?另请参见bashguru.com/2009/09/how-to-read-user-input-within-time.html
Panther

Answers:


3

这是使用-t timeoutbash 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


谢谢,这对我来说在我当前的Linux级别上更容易理解。但是无论如何我还是喜欢简单,几个月后总是更容易阅读和理解。
LinuxFerLife

1

这是另一种方法:

#!/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需要一个实际的过程,而不是shell命令。在这里,我们将bashshell作为单独的进程生成,并让它完成驱动工作select
  • printf用于外部timeout以避免通过管道发送其文本
  • while read -r answer; do . . .done当且仅当它通过管道接收到某些东西时,它才会运行。因此,如果先前的bash进程超时,它将无法运行-您的默认操作是不执行任何操作。
  • 如果while循环是通过管道接收到的东西,它将检查是否是yes答案,否则-它将不执行任何操作

谢谢,但是我更喜欢SteelDriver提供的选项。感谢您抽出宝贵的时间来描述正在发生的事情。
LinuxFerLife
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.