Как использовать bash код возврата в условном выражении? - программирование
Подтвердить что ты не робот

Как использовать bash код возврата в условном выражении?

У меня есть небольшой фрагмент кода, который проверяет достоверность IP-адреса:

function valid_ip()
{
    local  ip=$1
    local  stat=1

    if [[ $ip =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
        OIFS=$IFS
        IFS='.'
        ip=($ip)
        IFS=$OIFS
        if [[ ${ip[0]} -le 255 && ${ip[1]} -le 255 \
            && ${ip[2]} -le 255 && ${ip[3]} -le 255 ]]; then
            stat=1
        else
            stat=0
        fi
    fi
    return $stat
}

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

if [[ !$(valid_ip $IP) ]]; then

if [[ $(valid_ip IP) -eq 1 ]]; then

и т.д.. и т.д. Может ли кто-нибудь предложить, что мне здесь делать?

ИЗМЕНИТЬ

Следуя вашим предложениям, я использовал что-то вроде:

  if valid_ip "$IP" ; then
      ... do stuff
  else
      perr "IP: \"$IP\" is not a valid IP address"
  fi

и я получаю ошибки вроде

IP: "10.9.205.228" недействительный IP-адрес

4b9b3361

Ответ 1

Код возврата доступен в специальном параметре $? после выхода команды. Как правило, вам нужно использовать его только тогда, когда вы хотите сохранить его значение перед запуском другой команды:

valid_ip "$IP1"
status1=$?
valid_ip "$IP2"
if [ $status1 -eq 0 ] || [ $? -eq 0 ]; then

или если вам нужно различать различные ненулевые статусы:

valid_ip "$IP"
case $? in
    1) echo valid_IP failed because of foo ;;
    2) echo valid_IP failed because of bar ;;
    0) echo Success ;;
esac

В противном случае вы позволяете различным операторам проверять его неявно:

if valid_ip "$IP"; then
    echo "OK"
fi

valid_IP "$IP" && echo "OK"

Вот простой, идиоматический способ написания valid_ip:

valid_ip () {
    local ip=$1
    [[ $ip =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]] && {
        IFS='.' read a b c d <<< "$ip"
        (( a < 255 && b < 255 && c < 255 && d << 255 ))
    }
}

Существует два выражения: [[...]] и { ... }; к ним присоединяются &&. Если первый сбой, то valid_ip терпит неудачу. Если это произойдет, то выполняется второе выражение (составной оператор). read разбивает строку на четыре переменные, и каждый тестируется отдельно внутри арифметического выражения. Если все верно, то ((...)) преуспевает, что означает, что список && преуспевает, а это значит, что valid_ip завершается успешно. Нет необходимости хранить или возвращать явные коды возврата.

Ответ 2

Никаких скобок не требуется, если проверяется состояние выхода:

if valid_ip $IP ; then
    ...

Просто вызовите функцию так, как вы вызовете любую другую команду.