создать массив из исходного массива, но на основе того, где работает код? - PullRequest
0 голосов
/ 25 апреля 2018

У меня есть три машины (каждый в своем центре данных) в массиве machines.

  • Если мой сценарий оболочки работает в abc центре обработки данных, то я хочу получать файлы scp из machineA.abc.host.com, который будет моим локальным ящиком.Я выберу два других блока в качестве удаленных серверов для копирования файлов, если локальный блок отключен.
  • Если мой сценарий оболочки работает в def центре обработки данных, тогда я хочу получать файлы scp из machineB.def.host.com, который будет моим локальнымкоробка.Я выберу два других блока в качестве удаленных серверов для копирования файлов, если локальный блок не работает.
  • Если мой сценарий оболочки работает в pqr центре обработки данных, то я хочу получать файлы scp из machineC.pqr.host.com, который будет моим локальнымкоробка.Я выберу два других блока в качестве удаленных серверов для копирования файлов, если локальный блок отключен.

Ниже приведен мой сценарий, но я считаю, что это можно сделать гораздо лучше, чем использовать три разные переменные, а затемс тремя состояниями scp, разделенными на или:

machines=(machineA.abc.host machineB.def.host.com machineC.pqr.host.com)

case $(hostname -f) in
    *abc.host.com)
        local_server=("${machines[0]}")
        primary_remote==("${machines[1]}")
        secondary_remote==("${machines[2]}")
        ;;
    *def.host.com)
        local_server=("${machines[1]}")
        primary_remote==("${machines[2]}")
        secondary_remote==("${machines[0]}")
        ;;
    *pqr.host.com)
        local_server=("${machines[2]}")
        primary_remote==("${machines[0]}")
        secondary_remote==("${machines[1]}")        
        ;;
    *) echo "unknown host: $(hostname -f), exiting." >&2 && exit 1 ;;
    # ?
esac

export local="$local_server"
export remote1="$primary_remote"
export remote2="$secondary_remote"

copyFiles() {
  el=$1
  primsec=$2
  # can we just iterate from for loop instead of writing three scp statements?
  (scp -C -o StrictHostKeyChecking=no goldy@"$local":/proc/data/abc_187_"$el"_111_8.data "$primsec"/.) ||   (scp -C -o StrictHostKeyChecking=no goldy@"$remote1":/proc/data/abc_187_"$el"_111_8.data "$primsec"/.) ||   (scp -C -o StrictHostKeyChecking=no goldy@"$remote2":/proc/data/abc_187_"$el"_111_8.data "$primsec"/.)

}
export -f copyFiles

# using gnu parallel here to call above methods parallely

Теперь, как вы можете видеть, у меня есть три оператора scp, один для локального блока, другой для remote1 и remote2.Я думаю, что, возможно, мы сможем избавиться от этих трех операторов scp и вместо этого сохранить имена хостов (в определенном порядке, первый индекс может быть локальным блоком, а два других могут быть удаленными) в массиве, а затем перебрать этот массив из цикла forи просто написать одну инструкцию scp?

for p in "$machines"; do scp -C -o StrictHostKeyChecking=no goldy@"$p":/proc/data/abc_187_"$el"_111_8.data "$primsec"/. && break; done > /dev/null 2>&1

Если это возможно, то как я могу соответственно переставить массив machines или, возможно, создать другой массив, отличающийся от правильной машины в них с правильным индексом?

Обновление:

Каким-то образом цикл for внутри этой функции вообще не работает:

copyFiles() {
  local el=$1
  local primsec=$2
  local remote_file="/proc/data/abc_187_${el}_111_8.data"
  for host in "${hosts[@]}"; do
    echo "$host"
    echo "scp -C -o StrictHostKeyChecking=no "goldy@$host:$remote_file" "$primsec"/." && break
  done
}
export hosts
export -f copyFiles

parallel -j 5 copyFiles {} $proc::: ${pro[@]} &
parallel -j 5 copyFiles {} $data::: ${seco[@]} &
wait
echo "everything copied"

1 Ответ

0 голосов
/ 25 апреля 2018

Как насчет этого: он использует

  • ассоциативный массив для хранения "локальных" имен компьютеров
  • массив для хранения последовательности хостов для scp
  • цикл for для перебора возможных хостов и прерывания после первого успешного scp
#!/bin/bash
declare -A machines=(
    [abc]=machineA.abc.host.com
    [def]=machineB.def.host.com 
    [pqr]=machineC.pqr.host.com
)

IFS=. read -a host_parts < <(hostname -f)

case "${host_parts[1]}" in
    abc) hosts=( "${machines[abc]}" "${machines[def]}" "${machines[pqr]}" ) ;;
    def) hosts=( "${machines[def]}" "${machines[pqr]}" "${machines[abc]}" ) ;;
    pqr) hosts=( "${machines[pqr]}" "${machines[abc]}" "${machines[def]}" ) ;;
    *) echo "unknown host: $(hostname -f), exiting." >&2; exit 1 ;;
esac

copyFiles() {
    local el=$1
    local primsec=$2
    local remote_file="/proc/data/abc_187_${el}_111_8.data"
    for host in "${hosts[@]}"; do
        scp -C -o StrictHostKeyChecking=no "goldy@$host:$remote_file" "$primsec"/. && break
    done
}

export hosts
export -f copyFiles
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...