Bash скрипт if / then с несколькими условиями - PullRequest
0 голосов
/ 05 апреля 2020

Я хочу распечатать имя хоста и CNAME только в том случае, если статус DNS: «NXDOMAIN» ИЛИ «SERVFAIL» И имеет «CNAME».

Условия:

dig @8.8.8.8 -t A ${hstnm} | grep -q 'NXDOMAIN'
dig @8.8.8.8 -t A ${hstnm} | grep -q 'SERVFAIL'
dig @8.8.8.8 -t CNAME $hstnm +short >/dev/null

Итак Я написал ниже bash скрипт, но он не работает, любая помощь очень ценится, спасибо.

for hstnm in $(cat /path/file.txt)
do
if dig @8.8.8.8 -t A ${hstnm} | grep -q 'NXDOMAIN' || dig @8.8.8.8 -t A ${hstnm} | grep -q 'SERVFAIL' && dig @8.8.8.8 -t CNAME $hstnm +short >/dev/null ]]
then
echo -n -e "\e[92mNXDOMAIN: \e[0m${hstnm} "
echo -n -e "\e[93mCNAME: \e[0m"; dig @8.8.8.8 -t CNAME $hstnm +short
echo
fi
done

Ответы [ 2 ]

1 голос
/ 05 апреля 2020

ОК, давайте обозначим ваши условия:

  • A - dig @8.8.8.8 -t A "$hstnm" | grep -q 'NXDOMAIN'
  • B - dig @8.8.8.8 -t A "$hstnm" | grep -q 'SERVFAIL'
  • C - dig @8.8.8.8 -t CNAME "$hstnm" +short >/dev/null

Теперь, с этими именами, сообщите нам на языке алгоритми c, какой тест вы хотите.
Также нам нужно знать оболочку, которую вы используете (BASh? Korn? Almiqui sh? Z?)
В зависимости от этих параметров мы можем предоставить лучшую индикацию. Например,

#!/bin/bash

for hstnm in $(cat /path/file.txt)
do
if ( dig @8.8.8.8 -t A "$hstnm" | grep -q 'NXDOMAIN' ) || ( dig @8.8.8.8 -t A "$hstnm" | grep -q 'SERVFAIL' ) && ( dig @8.8.8.8 -t CNAME "$hstnm" +short >/dev/null )
then
echo -n -e "\e[92mNXDOMAIN: \e[0m${hstnm} "
echo -n -e "\e[93mCNAME: \e[0m"; dig @8.8.8.8 -t CNAME "$hstnm" +short
echo
fi
done

предположим, что "A или B затем C" ...


edit-2020-08-04 Итак, вы пытаетесь достичь «ЕСЛИ (« А »или« В »- истина) и (« C »- истина), ТО« 1010 * Первая часть »,« А »или« В »- истина», должна переводиться на A || B т.е.

if ( dig @8.8.8.8 -t A "$hstnm" | grep -q 'NXDOMAIN' ) || ( dig @8.8.8.8 -t A "$hstnm" | grep -q 'SERVFAIL' )
then
#foo
fi

Во-первых, я группирую "A" и "B" в скобках ... или в фигурных скобках. Если я не сделаю этого, я немного удивительно изменил значение: dig @8.8.8.8 -t A "$hstnm" | grep -q 'NXDOMAIN' || dig @8.8.8.8 -t A "$hstnm" | grep -q 'SERVFAIL' попросите оболочку

  • найти в Google адрес хоста и проверьте, нет ли такого домена "answer.
  • когда эта проверка не удалась (двойная труба), найдите в Google тот же адрес хоста и проверьте, есть ли ответ" проблема с сервером доменных имен ".
  • , но когда первая проверка не завершится неудачно, других копаний нет (что нормально), но некоторые оболочки будут продолжены и передадут предыдущий вывод команде grep '(я не проверял, как ведет себя мой bash, но это не так хорошо полагаться на такие вещи) ... что приведет к большому сбою (потому что мы идем от тихой проверки, поэтому в канале нет ввода для второй проверки, которая потребляет)

Итак, вы видите, почему здесь круглые скобки. Но будьте осторожны: совместимые с bourne оболочки не имеют скобок для группировки логических операций, как во многих языках программирования. Фактически, мы не используем логическое переключение, а только способность оболочки вызывать команду, основанную на успехе или неудаче предыдущей команды (это не совсем ложная система, как в других местах, даже при использовании таких команд, как * 1038). *) Несмотря на сходство, команда группы в скобках в подоболочке (используйте фигурные скобки, если вы не хотите использовать подоболочку и используйте некоторые переменные, проходящие вверх и вниз). Когда группа обрабатывается, она потерпит неудачу или преуспеет как blo c и имеет код возврата последней команды, запущенной в группе.

Теперь мы можем подумать об использовании группировки группировки для достижения наших целей.

if { ( dig @8.8.8.8 -t A "$hstnm" | grep -q 'NXDOMAIN' ) || ( dig @8.8.8.8 -t A "$hstnm" | grep -q 'SERVFAIL' ) } && ( dig @8.8.8.8 -t CNAME "$hstnm" +short >/dev/null )
then
#foo
fi

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

if ( dig @8.8.8.8 -t A "$hstnm" | grep -q 'NXDOMAIN' ) || ( dig @8.8.8.8 -t A "$hstnm" | grep -q 'SERVFAIL' )
then 
  if dig @8.8.8.8 -t CNAME "$hstnm" +short >/dev/null
  then
  #foo
  fi
fi

, которым нужно следовать.

0 голосов
/ 08 апреля 2020

Это то, что ваше сообщение в настоящее время говорит (упрощенно):

if A || B && C ]]
then
  ...
fi

Просто отбросьте конечный ]].

Вам не нужно добавлять какие-либо группировки, так как в отличие от многих языки, A || B && C в этом контексте в Bash эквивалентно (A || B) && C

...