Захват вывода команды в локальную переменную и проверка на наличие ошибок

#bash #error-handling

#bash #обработка ошибок

Вопрос:

У меня есть скрипт bash, в котором мне нужно запросить пароль. Я использую whiptail для захвата пароля. Мне нужно иметь возможность различать пустой пароль и выбранную кнопку «Отмена». Отмена обычно возвращает код ошибки 1.

Почему следующий код не обнаруживает, что пользователь нажимает кнопку «Отмена»?

 #!/bin/bash

function get_password() {
    local password=`whiptail --clear 
        --title "Password" 
        --passwordbox "Enter your login password:" 
        8 68 
        2>amp;1 >/dev/tty`
    local err=$?
    if [ "$err" -ne 0 ]; then
        >amp;2 echo "Cancelled"
        return 1
    fi
    if [ -z "$password" ]; then
        >amp;2 echo "No password entered"
        return 1
    fi

    echo "Password entered: $password"
}

get_password
  

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

Комментарии:

1. Что здесь не работает? cancel обнаружение?

2. @Anubis, код, как показано выше, никогда не будет err установлен в 1, если пользователь отменит его. Если я удалю local ключевое слово (создав password глобальную переменную), код правильно определит выбранную кнопку отмены.

Ответ №1:

local является командой, поэтому $? статус local , который выполняется независимо от статуса замены команды.

Если вы хотите, чтобы переменная была локальной, сначала объявите ее, а затем используйте:

 local password
password=`whiptail --clear 
    --title "Password" 
    --passwordbox "Enter your login password:" 
    8 68 
    2>amp;1 >/dev/tty`
  

Ответ №2:

Код выхода local password=$(...) — это статус local команды (который в идеале должен быть 0 ). local обрабатывается как команда, и код возврата $(...) переопределяется этим.

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

т.е.

 local password    # return code of this is always 0
password=`whiptail --clear 
    --title "Password" 
    --passwordbox "Enter your login password:" 
    8 68 
    2>amp;1 >/dev/tty`
local err=$?    
  

Комментарии:

1. Doh. Спасибо, это имеет смысл. Каким-то образом я не вывел это из какой-либо документации bash, с которой я столкнулся.