Như những người khác đã giải thích, sử dụng inotify
là giải pháp tốt hơn. Tôi sẽ chỉ giải thích tại sao kịch bản của bạn thất bại. Trước hết, cho dù bạn đang lập trình bằng ngôn ngữ nào, bất cứ khi nào bạn cố gắng gỡ lỗi một cái gì đó, quy tắc đầu tiên là "in tất cả các biến":
$ ls
file1 file2 file3
$ echo $PWD
/home/terdon/foo
$ for FILE in "${PWD}/*"; do echo "$FILE"; done
/home/terdon/foo/*
Vì vậy, như bạn có thể thấy ở trên, $FILE
thực sự được mở rộng đến $PWD/*
. Do đó, vòng lặp chỉ được chạy một lần trên chuỗi /home/terdon/foo/*
chứ không phải trên từng tệp trong thư mục riêng lẻ. Sau đó, md5sum
lệnh trở thành:
md5sum /home/terdon/foo/*
Nói cách khác, nó chạy md5sum
trên tất cả các tệp trong thư mục đích cùng một lúc chứ không phải trên mỗi tệp.
Vấn đề là bạn đang trích dẫn việc mở rộng toàn cầu của mình và điều đó ngăn không cho nó được mở rộng:
$ echo "*"
*
$ echo *
file1 file2 file3
Mặc dù các biến số hầu như luôn luôn được trích dẫn , nhưng các khối không nên vì điều đó làm cho chúng thành các chuỗi thay vì các chuỗi.
Những gì bạn muốn làm là:
for FILE in "${PWD}"/*; do ...
Tuy nhiên, không có lý do để sử dụng $PWD
ở đây, nó không thêm bất cứ điều gì hữu ích. Dòng trên tương đương với:
for FILE in *; do
Ngoài ra, tránh sử dụng các chữ cái VỐN cho các biến shell. Chúng được sử dụng cho các biến môi trường do hệ thống thiết lập và tốt hơn là giữ các biến của riêng bạn trong trường hợp thấp hơn.
Với tất cả những điều này, đây là phiên bản cải tiến của tập lệnh của bạn:
#!/bin/bash
for file in *
do
sum1="$(md5sum "$file")"
sleep 2
sum2="$(md5sum "$file")"
if [ "$sum1" = "$sum2" ];
then
echo "Identical"
else
echo "Different"
fi
done
for FILE in "${PWD}"/*; do
hoạt động trên cùng một tập hợp vìfor FILE in *; do
nó không chính xác tương đương vì cái sau không bao gồm tên đường dẫn.