Я получаю успешный вывод, когда запускаю сценарий ниже. То, что я пытаюсь здесь, это то, что я должен подключиться ко всем перечисленным ниже виртуальным машинам, и когда script ssh для wasadmds03, он должен распечатать вывод как product detail, аналогично для других виртуальных машин, а также должен выполнить команду "cat /source/package.json | версия grep" на всех виртуальных машинах.

Я получаю на выходе то, что мне нужно, но есть ли способ обрезать повторяющийся оператор «если тогда»? Я использовал оператор «if then» четыре раза, представьте, если я хочу сделать подобное упражнение для 50 виртуальных машин, есть ли способ написать эту программу короче?

wasadmds03 - product detail
wasadmds04 - product list
wasadmls03 - Cart
wasadmls05 - checkout
  • Сценарий

**

#!/bin/bash
for i in `cat /tmp/ms_test`
do
        if [ $i = wasadmds03 ]
        then
            echo "Product Detail"
            ssh $i "cat /source/package.json | grep version"
        fi
        if [ $i = wasadmds04 ]
        then
            echo "Product list"
            ssh $i "cat /source/package.json | grep version"
        fi
        if [ $i = wasadmls03 ]
        then
            echo "Merchant"
            ssh $i "cat /source/package.json | grep version"
        fi
        if [ $i = wasadmls05 ]
        then
            echo "Account Details"
            ssh $i "cat /source/package.json | grep version"
        fi
done
0
Surendar 19 Апр 2020 в 09:30
Привет. Может ли кто-нибудь помочь в этом запросе?
 – 
Surendar
19 Апр 2020 в 06:04
Что в /tmp/ms_test?
 – 
Kusalananda
19 Апр 2020 в 09:57
По крайней мере, я бы использовал elif вместо fi;if, чтобы он проверял все регистры перед выходом из цикла. Но да, мне тоже интересно, что находится в файле /tmp/ms_test.
 – 
admstg
19 Апр 2020 в 10:03
Файл /tmp/ms_test содержит имена виртуальных машин..(wasadmds03,wasadmds04,wasadmls03 и т.д..)
 – 
Surendar
19 Апр 2020 в 10:22
Даже если я использую elseif — предположим, если я проверяю это для 50 виртуальных машин, будет ли у него 50 условий else if? есть пути короче?
 – 
Surendar
19 Апр 2020 в 10:23

1 ответ

Лучший ответ

Таким образом, проблема заключается в том, что вы хотите вывести конкретную метку в зависимости от имени хоста, считанного из файла.

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

printf '%s\n' "${labels[$remote]}"
ssh -n "$remote" 'cat /source/package.json' | jq -r .version

... внутри цикла.

Здесь я позволил себе переименовать переменную цикла i в remote, что более наглядно. Я также использую printf вместо echo (см. "Почему printf лучше, чем echo?"), и я решил проанализировать этот файл данных JSON, используя настоящий анализатор JSON, jq, а не grep (это также означает, что я просто догадываюсь что в данных JSON есть ключ version верхнего уровня).

ssh должен вызываться с ssh -n, чтобы он не считывал входные данные, которые повторяет используемый нами цикл.

Массив labels может быть создан следующим образом:

declare -A labels
labels=(
    ['wasadmds03']='Product Detail'
    ['wasadmds04']='Product List'
    ['wasadmls03']='Merchant'
    ['wasadmls05']='Account Details'
)

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

Это, вместе с правильным чтением имен удаленных хостов из /tmp/ms_test (см. "Понимание "строки IFS= read -r"") дает нам следующий скрипт:

#!/bin/bash

declare -A labels
labels=(
    ['wasadmds03']='Product Detail'
    ['wasadmds04']='Product List'
    ['wasadmls03']='Merchant'
    ['wasadmls05']='Account Details'
)

while IFS= read -r remote; do
    printf '%s\n' "${labels[$remote]}"
    ssh -n "$remote" 'cat /source/package.json' | jq -r .version
done </tmp/ms_test
3
Kusalananda 19 Апр 2020 в 11:28
1
Спасибо Кусалананда, это сработало!!!!
 – 
Surendar
19 Апр 2020 в 11:33