使用此处文档为用户提供多种选择

Using here document to give user multiple options

在 shell 中,我想请用户在两个选项中选择一个,然后当 12 ,用它做一个switch语句。我该怎么做。

echo "Press [1] to transfer to $drive1"
echo "Press [2] to transfer to $drive2"

read #input somehow?

我试过将第二个 echo 变成一个 read。但理想情况下,我想将两个 echo 放入此处的文档中,然后将其应用于 read 但我无法获得正确的行。

options <<_EOF_

"Press [1] to transfer to $drive1"
"Press [2] to transfer to $drive2"

_EOF_
read $options -n 1

但我收到错误 line 7: options: command not found

您想做两件事:

  1. 给用户写一条消息
  2. 读一个数

这是两个完全独立的操作,您不应尝试将它们结合起来。要在此处的文档中写出消息,请使用 cat:

cat << EOF
Press [1] to transfer to $drive1
Press [2] to transfer to $drive2

EOF

读取一个数字:

read -n 1 option

全都在这里:

#!/bin/bash
cat << EOF
Press [1] to transfer to $drive1
Press [2] to transfer to $drive2

EOF

read -n 1 option

echo
echo "You entered: $option"

可以

cat << PROMPT
Press [1] to transfer to $drive1
Press [2] to transfer to $drive2
PROMPT
read -n1 drivenumber
case "$drivenumber" in
    1) handle drive 1;;
    2) handle drive 2;;
    *) handle invalid input;;
esac

这将符合您提出的要求。但是你必须做额外的工作来避免无效输入:

input=
while true; do
    that whole thing
    validate_input && break
    echo "oh no your input was invalid"
done

此外,为了澄清我上面的 select 评论,当您想更改驱动器数量时,使用 heredoc 暗示的体系结构有点麻烦。

drives=( "$drive1" "$drive2" )
PS3="Choose a drive to transfer to"
select drive in "${drives[@]}"; do
    # really no need for a case statement anymore
    do_x_to "$drive"
done

或者你可以选择混合道路:

while true; do
    for i in "${!drives[@]}"; do
        printf 'Press [%d] to transfer to %s\n' "$i" "${drives[i]}"
    done
    read -n1 drive_number
    if [[ ! ${drives[drive_number]} ]]; then
        echo "invalid drive number" >&2
        continue
    fi
    drive=${drives[drive_number]}
    case "$drive" in …
    esac
done