将提示放入shell(带光标输入)*上方*选项列表

时间:2017-05-19 15:03:55

标签: linux bash

所以我想知道是否可以在控制台下面的上打印一些东西一个要求用户输入的提示。

read -p "Would you like to choose an apple or a pear? "
echo "5 apples"
echo "3 pears"

像这样的东西,你在第一行提示用户,但在它下面写了一些东西。我不知道如何解决这个问题,因为当我提示用户时,脚本执行会等待响应。

要清楚,我的意图是一个如下所示的提示,其中_表示光标位置:

Would you like to choose an apple or a pear? _
5 apples
3 pears

我正在尝试使用计时器在后台编写后续提示行,但如果可能的话,我会更喜欢解决此问题的其他角度。

2 个答案:

答案 0 :(得分:2)

快速说明 - 如果寻求与没有tput的基准POSIX shell或系统的兼容性,请参阅此问题的answer by @Attie。这个答案的优点是可以使用非ANSI终端,因为它使用tput,但另一个与更广泛的shell兼容。

tput可用于查找用于将光标移动到给定位置的相应控制序列。在下面的示例中,我们将从已清除的屏幕开始,因此我们知道提示将始终打印在左上角 - (0,0)

# start with an empty screen
clear

# print an empty line, then "5 apples" on the next line, and "3 pairs" on the third
printf '%s\n' '' "5 apples" "3 pairs"

# Move the cursor back to the top-left-corner
tput cup 0 0

# ...and print the prompt there.
read -p "Would you like to choose an apple or a pear? "

使用tput cuu将光标向上移动所需的行数,然后tput cud将其向下移动,可以避免首先清除屏幕的需要:

# print an empty line, then "5 apples" on the next line, and "3 pairs" on the third
printf '%s\n' '' "5 apples" "3 pairs"

# Move the cursor up three lines...
tput cuu 3

# ...and print the prompt there.
read -p "Would you like to choose an apple or a pear? "

# finally, after input has been entered, move the cursor down three lines
tput cud 3

答案 1 :(得分:1)

命令行界面通常首先显示选项,然后通过给定的默认响应询问第二个问题。我鼓励你这样做。

更典型的输出是:

Options:
  1.  Apple   (5 available)
  2.  Pear    (3 available)
What would you like? [1] _

在这种情况下,用户可以为Apple输入1,为梨输入2,或者默认输入任何内容(Apple,方括号中显示)。

注意:下划线用于显示光标的位置,显然是讨论的一部分。

可以将你的提示放在选项上方,但这需要你定位光标(并不总是支持),并且可能会给新用户带来一些困惑。您可能希望查看ANSI escape codes(或其某些抽象,例如:ncurses / tput)。

在下面的例子中,光标移动应该与输入循环紧密耦合(感谢@Charles的输入)。

# reserve a line
echo ''

# present options
echo '5 apples'
echo '3 pears'

# move 'up' 2x lines (n-options)
printf '%b' '\e[2A'

# get input
while [ 1 ]; do
    # move the cursor to column 1
    # move 'up' 1x line, and
    # clear to the end of the line
    printf '%b' '\e[G\e[1A\e[K'

    # prompt for input
    printf '%s' 'Would you like to choose an apple or a pear? '
    read choice

    # validate input
    case $choice in
        apple | \
        pear  )
            break
            ;;
    esac
done

# move 'down' 2x lines (n-options)
printf '%b' '\e[2B'

# output user's input
echo "User picked ${choice}"