У меня есть следующая функция

function executeMySql() {
  while IFS= read -p "$prompt" -r -s -n 1 char
  do
      if [[ $char == $'\0' ]]; then
          break
      fi
      if [[ $char == $'\177' ]];  then
          prompt=$'\b \b'
          password="${password%?}"
      else
          prompt='*'
          password+="$char"
      fi
  done
  mysql -u root -p$password -e "$1"
  ret=$?
  if [ $ret = "0" ]; then
    # Show success message
    printf "\e[32m\nSUCCESS: $2\n\n"
    tput sgr0
  else
      echo "Wrong password"
  fi
}

и я использую это так

echo -e "Enter your mysql \$root password to create the db"
executeMySql "CREATE DATABASE IF NOT EXISTS Test" "Test db ready"
{
  touch /var/moo.txt
} || {
  # ...
}

Но если пользователь вводит неправильный пароль mysql, он получает сообщение « Wrong password и сценарий продолжается, но я хочу зациклить попытки ввода пароля пользователя, пока он не будет успешным, и затем продолжить выполнение сценария.

Есть идеи, как этого добиться?

2 ответа2

1

Вызов mysql не находится внутри цикла, поэтому он будет вызываться только один раз, независимо от того, успешно он или нет.

Вы можете убедиться, что вы возвращаете $ret в конце executeMySql и вызываете его, используя:

while ! executeMySql ...; do :; done

или вы можете изменить executeMySql так, чтобы вызов mysql находился в существующем цикле:-

function executeMySql() {
  while IFS= read -p "$prompt" -r -s -n 1 char
  do
      if [[ $char == $'\177' ]];  then
          prompt=$'\b \b'
          password="${password%?}"
          continue
      elif [[ $char == $'\0' ]]; then
          prompt='*'
          password+="$char"
          continue
      fi
      # Drop through when $char == $'\0'
      mysql -u root -p$password -e "$1"
      ret=$?
      if [ $ret = "0" ]; then
        # Show success message
        printf "\e[32m\nSUCCESS: $2\n\n"
        tput sgr0
        return $ret
      else
          echo "Wrong password"
      fi
  done
}

Я проверил код на столе, но я не могу легко выполнить тест кода, поэтому я надеюсь, что изменил его правильно, хотя в противном случае это должно быть достаточным руководством к тому, что нужно делать.

Вы также можете добавить замкнутый цикл ret=1; while $ret != 0 ... в executeMySql , который, возможно, неуклюж, но требует меньше изменений кода.

0

Вот рабочая версия функции

function executeMySql() {
  local password
  local prompt
  local char
  while IFS= read -p "$prompt" -r -s -n 1 char
  do
      if [[ $char == $'\0' ]]; then
          break
      elif [[ $char == $'\177' ]];  then
          prompt=$'\b \b'
          password="${password%?}"
      else
          prompt='*'
          password+="$char"
      fi
  done
  mysql -u root -p$password -e "$1"
  ret=$?
  if [ $ret = "0" ]; then
    # Show success message
    echo -e "SUCCESS: $2"
  else
      echo -e "Wrong password try again"
  fi
  return $ret;
}

пример использования

echo -e "Enter your mysql \$root password to create the db"
while ! executeMySql "CREATE DATABASE IF NOT EXISTS Test" "Test db ready"; do :; done

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