如何在壳牌中随机挑选三台机器的第一台?



我有三台远程机器(机器A,机器B,机器C(,我可以从中复制文件。如果由于某种原因我无法从机器 A 复制,那么我应该从机器 B 复制,如果出于某种原因我不能从机器 B 复制,那么开始从机器 C 复制。

下面是我拥有的单个 shell 命令,我需要在许多机器上运行它,但这意味着在所有这些机器上,它只会从机器 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

将机器名称保存在文件中并使用 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[@]}洗牌数组。要将其读回数组,您需要将输出输入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

这里有一个小例子来说明你可以怎么做 - 它主要是评论,以显示我的想法,但你可以删除它们以使其简洁。

#!/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

最新更新