我有三台远程机器(机器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