Có nhiều điểm thất bại có thể có trong kịch bản của bạn. Trước hết, rm *.old*
sẽ sử dụng globalbing để tạo danh sách tất cả các tệp phù hợp và có thể xử lý tên tệp chứa khoảng trắng. Kịch bản của bạn, tuy nhiên, gán một biến cho từng kết quả của toàn cầu và thực hiện điều đó mà không cần trích dẫn. Điều đó sẽ phá vỡ nếu tên tệp của bạn chứa khoảng trắng. Ví dụ:
$ ls
'file name with spaces.old.txt' file.old.txt
$ rm *.old.* ## works: both files are deleted
$ touch "file.old.txt" "file name with spaces.old.txt"
$ for i in ./*; do oldfile=$i; rm -v $oldfile; done
rm: cannot remove './file': No such file or directory
rm: cannot remove 'name': No such file or directory
rm: cannot remove 'with': No such file or directory
rm: cannot remove 'spaces.old.txt': No such file or directory
removed './file.old.txt'
Như bạn có thể thấy, vòng lặp thất bại cho tệp có khoảng trắng trong tên của nó. Để làm điều đó một cách chính xác, bạn sẽ cần trích dẫn biến:
$ for i in ./*; do oldfile="$i"; rm -v "$oldfile"; done
removed './file name with spaces.old.txt'
removed './file.old.txt'
Vấn đề tương tự áp dụng cho hầu hết mọi sử dụng $i
trong tập lệnh của bạn. Bạn nên luôn luôn trích dẫn các biến của bạn .
Vấn đề có thể xảy ra tiếp theo là bạn dường như mong đợi *.old.*
khớp các tệp với tiện ích mở rộng .old
. Nó không. Nó khớp với "0 hoặc nhiều ký tự" ( *
), sau đó là a .
, rồi "cũ", rồi một ký tự khác .
và sau đó "0 hoặc nhiều ký tự nữa". Điều này có nghĩa là nó sẽ không khớp với một cái gì đó như file.old
, nhưng chỉ một cái gì đó như `file.old.foo:
$ ls
file.old file.old.foo
$ for i in *; do if [[ "$i" == *.old.* ]]; then echo $i; fi; done
file.old.foo
Vì vậy, không có kẻ thù phù hợp file.old
. Trong mọi trường hợp, kịch bản của bạn phức tạp hơn nhiều so với cần thiết. Hãy thử cái này thay thế:
#!/bin/bash
for i in *; do
if [[ -f "$i" ]]; then
if [[ "$i" == *.old ]]; then
rm -v "$i" || echo "rm failed for $i"
else
echo "$i doesn't have an .old extension"
fi
cp -v "$i" "$i".old
else
echo "$i is not a file"
fi
done
Lưu ý rằng tôi đã thêm -v
vào các câu lệnh rm
và cp which does the same thing as what you were doing with your
echo`.
Điều này không hoàn hảo vì khi bạn tìm thấy, ví dụ, file.old
nó sẽ bị xóa và sau đó, tập lệnh sẽ cố gắng sao chép nó và thất bại vì tệp không còn tồn tại. Tuy nhiên, bạn đã không giải thích những gì kịch bản của bạn thực sự đang cố gắng để tôi không thể khắc phục điều đó cho bạn trừ khi bạn cho chúng tôi biết những gì bạn đang thực sự cố gắng thực hiện.
Nếu điều bạn muốn là i) xóa tất cả các tệp có .old
tiện ích mở rộng và ii) thêm .old
tiện ích mở rộng vào bất kỳ tệp hiện có nào không có, tất cả những gì bạn thực sự cần là:
#!/bin/bash
for i in *.old; do
if [[ -f "$i" ]]; then
rm -v "$i" || echo "rm failed for $i"
else
echo "$i is not a file"
fi
done
## All the ,old files have been removed at this point
## copy the rest
for i in *; do
if [[ -f "$i" ]]; then
## the -v makes cp report copied files
cp -v "$i" "$i".old
fi
done
rm *.old.*
để loại bỏ các tệp này nhưng không phải là tập tin sao lưu file.old. Tôi đang cố gắng làm điều đó trong kịch bản của tôi. Cảm ơn