как выбрать первый случайный компьютер из трех в оболочке - PullRequest
0 голосов
/ 29 апреля 2018

У меня есть три удаленных компьютера (machineA, machineB, machineC), с которых я могу копировать файлы. Если по какой-либо причине я не могу скопировать с машины A, то я должен скопировать с машины B, а если по какой-либо причине я не могу скопировать с машины B, тогда начните копирование с машины C.

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

(ssh goldy@machineA 'ls -1 /process/snap/20180418/*' | parallel -j5 'scp goldy@machineA:{} /data/files/') || (ssh goldy@machineB 'ls -1 /process/snap/20180418/*' | parallel -j5 'scp goldy@machineB:{} /data/files/') || (ssh goldy@machineC 'ls -1 /process/snap/20180418/*' | parallel -j5 'scp goldy@machineC:{} /data/files/')

Теперь есть какой-нибудь способ, которым я могу выбрать первую машину случайным образом (из этих трех) вместо того, чтобы сохранять machineA как первый всегда. Итак, выберите первую машину случайным образом и оставьте две другие, так как резервная копия первой машины не работает? Возможно ли это сделать?

Обновление:

У меня есть что-то вроде этого:

  machines=(machineA machineB machineC)
  for machine in $(shuf -e ${machines[@]}); do
      ssh -o StrictHostKeyChecking=no david@$machine 'ls -1 /process/snap/{{ folder }}/*' | parallel -j{{ threads }} 'scp -o StrictHostKeyChecking=no david@${machine}:{} /data/files/'
      [ $? -eq 0 ] && break
  done

Ответы [ 2 ]

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

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

#!/bin/bash

# Machine names, number of machines, random starting index
machines=("machineA" "machineB" "machineC")
num=${#machines[@]}
idx=$((RANDOM%num))

# Make one try per machine, break on success
for ((try=0;try<num;try++)) ; do
   this=${machines[$idx]}
   echo $this
   ((idx=(idx+1)%num))
done

Итак, вы должны поместить свою команду в то место, где у меня есть echo $this, и следовать ей:

[ $? -eq 0 ] && break

Пример вывода

./go
machineB
machineC
machineA

Если у вас есть shuf, вы можете сделать то же самое более кратко, как это:

#!/bin/bash

# Machine names, in random order
machines=("machineA" "machineB" "machineC")
machines=( $(shuf -e "${machines[@]}") )

# Make one try per machine, break on success
for i in "${machines[@]}"; do
   echo $i
   ... your command
   [ $? -eq 0 ] && break
done
0 голосов
/ 29 апреля 2018

Как насчет хранения имен машин в файле и использования shuf для их перемешивания? Тогда вы можете создать такой скрипт:

while read machine; do
    ssh goldy@$machine 'ls -1 /process/snap/20180418/*' | parallel -j5 "scp goldy@$machine:{} /data/files/"
    if [ $? == 0 ]; then
        break
    fi
done

И машинный файл вот так:

machineA
machineB
machineC

И назовите скрипт так:

shuf machines | ./script.sh

Вот тестовая версия, которая ничего не делает, но показывает, как работает логика:

while read machine; do
    echo ssh goldy@$machine 'ls -1 /process/snap/20180418/*'
    echo parallel -j5 "scp goldy@$machine:{} /data/files/"
    executenonexistingcommand
    if [ $? == 0 ]; then
        break
    fi
done
<ч />

Обращаясь к вашему комментарию, используйте вместо него массивы и поместите все в одну строку:

shuf -e ${machines[@]} перемешивает массив. И чтобы прочитать его обратно в массив, вам нужно передать outpu в readarray. Чтобы превратить сценарии в одну строку, нужно просто поставить точки с запятой там, где раньше были строки.

machines=( machineA machineB machineC ); for machine in $(shuf -e ${machines[@]}); do ssh goldy@$machine 'ls -1 /process/snap/20180418/*' | parallel -j5 "scp goldy@${machine}:{} /data/files/"; if [ $? == 0 ]; then break; fi; done
...