1

У меня есть скрипт bash, который я хочу сделать что-то вроде

read one_thing
read another_thing

И затем он запускает некоторый код, чтобы увидеть, доступно ли another_thing или уже занято, и если оно занято, он должен предупредить пользователя и снова запустить

read another_thing

так что мы можем иметь новое значение, оставляя one_thing без изменений. Поскольку в bash нет goto , мне интересно, как это сделать. Мое лучшее предположение на данный момент заключается в том, что, возможно, мне следует заключить в функцию read another_thing внутри функции, чтобы при необходимости она просто вызывала себя, но я чувствую, что для этого должен быть более «чистый» способ. Я ищу предложения об эффективных способах сделать это.

2 ответа2

2

Вы можете проверить ваше состояние в цикле, и break из него , когда он встретил.

#!/bin/bash

read -p 'Input something > ' one_thing

while true; do
  read -p 'Input something else > ' another_thing

  # Write some code to check if the requirements are met
  # Let's say in this case they are when the variable `thing_to_work` equals `done`

  if [[ "${thing_to_work}" == 'abcde' ]]; then
    break # Exit the loop
  else
    echo 'The requirements were not met, so the loop will start again'
  fi
done
1

Когда я перешел с Windows на Linux на своем рабочем столе, у меня было много уже существующих .BAT и .CMD для конвертации, и я не собирался переписывать логику для них, поэтому я нашел способ сделать goto в bash, который работает, потому что функция goto запускает sed для себя, чтобы удалить любые части скрипта, которые не должны беги, а потом все это изгоняет

#!/bin/bash

# BAT / CMD goto function
function goto
{
    label=$1
    cmd=$(sed -n "/^:[[:blank:]][[:blank:]]*${label}/{:a;n;p;ba};" $0 | 
          grep -v ':$')
    eval "$cmd"
    exit
}

apt update

# Just for the heck of it: how to create a variable where to jump to:
start=${1:-"start"}
goto "$start"

: start
goto_msg="Starting..."
echo $goto_msg
# Just jump to the label:
goto "continue"

: skipped
goto_msg="This is skipped!"
echo $goto_msg

: continue
goto_msg="Ended..."
echo "$goto_msg"

# following doesn't jump to apt update whereas original does
goto update

и я совсем не чувствую себя виноватым, как сказал Линус Торвальдс:

От: Линус Торвальдс
Тема: Re: есть ли шанс в 2.6.0-тесте *?
Дата: вс, 12 января 2003 11:38:35 -0800 (PST)

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

Конечно, в глупых языках, таких как Pascal, где метки не могут быть описательными, goto могут быть плохими. Но это не вина goto, это мозговая атака дизайнера языка.

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

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .