Сценарий оболочки не перезапускается при вводе пользователя

Похоже, вы выбрали логические тома (LVM), а не разделы. Это не разделы, и они управляются с помощью другого механизма.

Попробуйте использовать команду LVM как sudo lvm lvs. В ней должны быть перечислены логические тома.

2
23.04.2018, 21:58
2 ответа

Вы забыли добавить orderк $, чтобы разыменовать его:

#!/bin/sh

echo $0

read -rp 'Fish or chicken? ' protein
read -rp 'Beans or rice? ' starch
read -rp 'Broccoli or asparagus? ' veggie
read -rp 'Beer or beer? ' drink

echo "You have ordered the $protein with a side of $starch and $veggie, and     to drink you will have $drink"

while true; do
    read -rp 'Would you like to order again? ' order
    if echo "$order" | grep -iq 'yes'; then
    exec $0
    elif echo "$order" | grep -iq 'no'; then
    exit 0
    fi
done

Также обратите внимание, что вы можете просто сравнивать строки с помощью =.

-1
27.01.2020, 22:09

Основная проблема с вашим сценарием заключается в том, что вы проверяете литеральную строку orderна предмет того, является ли она yesили нет. Вероятно, вы имели в виду "$order".

Другая проблема заключается в том, что вы запускаете этот скрипт, который является скриптом bash, используя /bin/sh. /bin/shможет не понимать некоторых расширений, которые bashвносит в стандарт оболочки POSIX, но вам может просто повезти. Измените первую строку, чтобы вместо нее использовалось bash.

Сравнение строк в сценарии оболочки можно выполнить с помощью

if [ "$order" = "yes" ]; then...; fi

Это «дешевле» и легче читать, чем вызов grep.

Вы также можете использоватьcase... esac:

case "$order" in
    yes)... ;;
    no) ... ;;
esac

Относительно -выполнения сценария для повторного запуска является хрупким и очень нетрадиционным. Например, скорее всего, он не будет работать, если скрипт вызывается как bash script.sh. Лучше ввести цикл, из которого вы выйдете, если пользователь не хочет делать еще одну попытку.

bashтакже имеет петлю select, которую вы можете использовать следующим образом:

echo 'Please select protein from this menu:'
select protein in "beans" "lentils" "tofu" "cheese"; do
    if [ -z "$protein" ]; then
        echo 'Invalid choice' >&2
    else
        printf 'You picked %s as protein\n' "$protein"
        break
    fi
done

Это позволяет лучше контролировать ввод данных пользователем.


Общий подход к чтению интерактивного ввода от пользователя с последующим вопросом о выходе или отказе:

while true; do
    read -p 'Enter data: ' -r data
    # use "$data" here for something

    read -p 'Again? [Y/n] ' answer

    case "$answer" in
        [Nn]*) break ;;
    esac
done

Здесь у вас есть внешний цикл, который задает вопросы и выполняет некоторую обработку. Затем он спрашивает пользователя, хотят ли они пойти еще раз. Если они ответят «Нет» (что-либо, начинающееся с Nили n), мы breakвыбываем из цикла.

Тест в конце также может быть проверкой $data. Если пользователь ввел неверный ввод в первый read, вы можете захотеть повторить запрос, пока не будет дан правильный ввод.

Преимущество этого в том, что$data(или то, что вы читаете ), живо и доступно после цикла ввода,поэтому вместо обработки $dataвнутри цикла вы можете сделать это позже.

Псевдокод:

input-loop:
    read-data
    validate-data
    if-valid exit input-loop
    goto input-loop

main-code:
    use-validated-data
3
27.01.2020, 22:09

Теги

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