Выполнить PIPE для строки, не найденной в выводе bash - PullRequest
0 голосов
/ 19 декабря 2018

Мой желаемый поток результатов, как показано ниже: но я не уверен, как использовать цикл for здесь.Пожалуйста, обратите внимание, в моем выражении, где пытается проверить строку1 не существует в выходных данных каждого узла.

  • получить вывод команды, которая соответствует строке DISABLED, которая дает список соответствующих узлов.Пример:

    kubectl get nodes | grep -i DISABLED
    

    Пример: выходные данные равны

    node1-DISABLED node2-DISABLED node3-DISABLED
    
  • для каждого из узлов, которые я получаю выше, я описываю их как Ex:

    kubectl describe nodes $1
    
  • , затем при выводе description я хочу увидеть, что все узлы НЕ имеют строку "string1" в своей команде вывода output описаний, а затем, если не найден, вывести эхо / распечататьузел

Итак, мое полное выражение выглядит следующим образом

kubectl get nodes | grep -i DISABLED | 
awk -F ' ' '{print $1}' | 
xargs -l1 -- sh -c 'kubectl describe node "$1"' | 
for grep -e "string1" == 0; do 
xargs -l1 -- sh -c 'echo "$1"' --; done

Пример вывода частичных команд:

bash$ kubectl get nodes | grep -i DISABLED
10.4.5.15-59fa4f88   Ready,SchedulingDisabled   node      20d       v1.10.9   <none>        Ubuntu 16.04.4 LTS   4.15.0-15-generic   docker://18.3.1

10.4.5.16-59fa4f88   Ready,SchedulingDisabled   node      20d       v1.10.9   <none>        Ubuntu 16.04.4 LTS   4.15.0-15-generic   docker://18.3.1


bash$ kubectl get nodes | grep -i DISABLED | awk -F ' ' '{print $1}'
10.4.5.15-59fa4f88
10.4.5.16-59fa4f88

Ожидаемый вывод:

10.4.5.15-59fa4f88

Поскольку узел 10.4.5.15-59fa4f88 не имеет string1 в выходных данных описания, а 10.4.5.16 не отображается, потому что в его описании есть выход string1.

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

Выход

kubectl describe node $1

Name:               10.4.5.15-59fa4f88
Roles:              node
Labels:             beta.kubernetes.io/arch=amd64
                beta.kubernetes.io/instance-type=gdd5_8dd.dd2xlarge
                beta.kubernetes.io/os=linux
                failure-domain.beta.kubernetes.io/zone=sdjcd2d01-sw-05
                kops.k8s.io/instancegroup=nodes-test
                kubernetes.io/hostname=10.4.5.15-59fa4f88
                kubernetes.io/role=node
                node-role.kubernetes.io/node=
Annotations:        d.volume.kubernetes.io/nodeid={"d-d":"10.4.5.15-59fa4f88"}
                node.alpha.kubernetes.io/ttl=0
                volumes.kubernetes.io/controller-managed-attach-detach=true
CreationTimestamp:  Wed, 28 Nov 2018 07:37:39 -0800
Taints:             <none>

1 Ответ

0 голосов
/ 19 декабря 2018

Я думаю, ваш код может быть существенно упрощен.Попробуйте это:

kubectl get nodes |
# Awk can do everything grep can do, and then some
awk 'toupper($0) ~ /DISABLED/ { print $1 }' |
# loop over results
while read -r node; do
    kubectl describe node "$node" |
    grep -q "string1" || echo "$node"
done

Если вывод kubectl describe node где-то содержит имя узла (скажем, первое поле?), Тогда цикл while может быть заменен чем-то вроде

# xargs already knows how to run a command
xargs -n 1 kubectl describe node |
# Simply filter out anything with string1
awk '! /string1/ { print $1 }'

Если вы хотите отсеять дубликаты, нажмите | sort -u или в последнем случае реализуйте простое удаление дубликатов в скрипте Awk (подсказка: сохраняйте ассоциативные массивы значений, которые вы видели, и печатайте только тогда, когда что-то не так ')t уже в массиве).

Обновлено в ответ на редактирование: Вот попытка Awk, которая извлекает и печатает поле Name: если ни один из выходных данных не содержит start1.

kubectl get nodes |
awk 'toupper($0) ~ /DISABLED/ { print $1 }' |
xargs -n 1 kubectl describe node |
awk '/^Name: / { if (NR>1 && name) print name
        name=$2 }
    /string1/ { name="" }
    END { if (name) print name }'

Сценарий Awk назначит name, когда увидит начало нового вывода.Если был установлен предыдущий name, то сначала мы его печатаем (предыдущая запись).Второе регулярное выражение сбрасывает name, если оно видит string1, так что оно не будет напечатано, когда мы достигнем следующей записи.Наконец, в END мы ловим фамилию, если она была установлена.

...