以下のシェルスクリプトをmachineCで実行しています。このスクリプトは、machineC自体のPRIMARYディレクトリにあるファイルのmd5sumを取得します。
#!/bin/bash
export PRIMARY=/data01/primary
for entry in "$PRIMARY"/*
do
local_md5sum=$(/usr/bin/md5sum "$entry" | awk '{print $1}')
echo $local_md5sum
done
上記のシェルスクリプトを実行するとすぐに、machineC内のファイルのmd5sumが出力され、正常に動作します。
これで、md5sumを計算している同じファイルがmachineAまたはmachineBのいずれかにある可能性があるため、machineAとmachineBでsshを実行し、同じファイルで同じmd5sumを実行して、remote_md5sum
変数に格納する必要があります。
ファイルがmachineAにない場合は、確実にmachineBにあるはずであり、ファイルはmachineAとmachineBのこのディレクトリにあります。
/bat/test/data/snapshot/20140918
だから私はmachineCで実行しているシェルスクリプトの下に来て、machineAまたはmachineB上のファイルのmd5sumを見つけようとしています
#!/bin/bash
# folder in machineC
export PRIMARY=/data01/primary
readonly SERVERS=(machineA machineB)
export SERVERS_1=${SERVERS[0]}
export SERVERS_2=${SERVERS[1]}
export FILES_LOCATION=/bat/test/data/snapshot/20140918
for entry in "$PRIMARY"/*
do
# find local md5sum on machineC
local_md5sum=$(/usr/bin/md5sum "$entry" | awk '{print $1}')
echo $local_md5sum
# find remote md5sum of the file which will be on machineA or machineB
remote_md5sum=$(ssh user@$SERVERS_1 /usr/bin/md5sum "$entry" | awk '{print $1}' || ssh bullseye@$SERVERS_2 /usr/bin/md5sum "$entry" | awk '{print $1}')
echo "Remote Checksum: $remote_md5sum"
# now compare local_md5sum and remote_md5sum
done
しかし、シェルスクリプトの上で実行すると、sshコマンドが失敗し、そのファイルのmd5sum値がremote_md5sum
に保存されません。この構文に何か問題がありますか?
remote_md5sum=$(ssh user@$SERVERS_1 /usr/bin/md5sum "$entry" | awk '{print $1}' || ssh user@$SERVERS_2 /usr/bin/md5sum "$entry" | awk '{print $1}')
スクリプトを変更しましたが、これで動作します。スクリプトをわかりやすくするために、スクリプト内にコメントをいくつか追加しました。さらにサポートが必要な場合はお知らせください。
#!/bin/bash
#The export path which we set here.
export PRIMARY=/home/ramesh
#The main for loop execution starts here.
for entry in "$PRIMARY"/*
do
#Get the base name of the file which we check in the remote servers.
#Get just the filenames without the path.
#I am going to use the filename in the remote server to check.
filename=$(basename "$entry")
echo "File Name: $filename"
#Calculate the MD5Sum locally.
local_md5sum=$(md5sum "$entry")
echo "Local MD5Sum: $local_md5sum"
#Check if the file exists in server1.
#Otherwise I can check in the other server.
if ssh ramesh@server1 stat /home/ramesh/'$filename' \> /dev/null 2\>\&1 then
#I have the file in server1 and so I get the md5sum from server1.
#I store the md5sum inside remote_md5sum variable.
remote_md5sum=$(ssh ramesh@server1 "cd /home/ramesh/; find -name '$filename' -exec md5sum {} \;")
else
#Now, I know the file is in server2 as it is not present in server1.
remote_file=$(ssh ramesh@server2 "cd /home/ramesh/; find -name '$filename' -exec md5sum {} \;")
fi
echo "Remote MD5Sum: $remote_file"
done
テスト
上記のスクリプトで、スペースを含むファイル名もテストしたいと思いました。これはうまく機能し、これはスクリプトを実行したときに得られる出力です。
File Name: file1
Local MD5Sum: 39eb72b3e8e174ed20fe66bffdc9944e /home/ramesh/file1
Remote MD5Sum: b5fc751f836c5430b617bf90a8c4725d ./file1
File Name: file with spaces
Local MD5Sum: 36707e275264f4ac25254e2bbe5ef041 /home/ramesh/file with spaces
Remote MD5Sum: 36707e275264f4ac25254e2bbe5ef041 ./file with spaces
まず、変数FILES_LOCATION
を使用することはありません。それはそれを役に立たなくします。第二に、シェルではそのように||
を使用することはできません。
次のようなものを試してください:
entry="$FILES_LOCATION/$(basename "$entry")"
remote_md5sum=$(ssh user@$SERVERS_1 /usr/bin/md5sum "$entry" | awk '{print $1}')
if [ -z $remote_md5sum ] ; then
remote_md5sum=$(ssh user@$SERVERS_2 /usr/bin/md5sum "$entry" | awk '{print $1}')
fi
これを行うための迅速で簡単な方法は次のとおりです(「machine2」で「user1」として実行されるすべてのコマンド)。
[user1@machine2]$ cd /home/user1/src
[user1@machine2]$ ssh user1@machine1 "cd src;find . -type f -exec md5sum {} \;" | md5sum --check | grep -v "OK"
シナリオに合わせてディレクトリを変更します。
私はこれを2007年にネットのどこかで拾いました。それは役に立ちます。