Không có cách nào thấp để trao đổi các tệp trong các hệ thống Unix truyền thống, vì vậy bạn cần sử dụng tên tạm thời trung gian. Để chắc chắn, hãy đảm bảo rằng tên tạm thời sẽ không được sử dụng bởi bất kỳ chương trình nào khác (vì vậy sử dụng mktemp
) và nó trên cùng một hệ thống tệp với một trong các tệp (nếu không các tệp sẽ được sao chép một cách không cần thiết thay vì chỉ được đổi tên).
swap_files () {
tmp_name=$(TMPDIR=$(dirname -- "$1") mktemp) &&
mv -f -- "$1" "$tmp_name" &&
mv -f -- "$2" "$1" &&
mv -f -- "$tmp_name" "$1"
}
swap_files file file_1
Xin lưu ý rằng nếu xảy ra lỗi, tệp đầu tiên vẫn có thể nằm dưới tên tạm thời và tệp thứ hai có thể hoặc chưa được di chuyển. Nếu bạn cần sự mạnh mẽ trong trường hợp bị gián đoạn và gặp sự cố, một biến thể có hai tên tạm thời có thể dễ dàng phục hồi hơn.
swap_files2 () {
tmp_dir1=$(TMPDIR=$(dirname -- "$1") mktemp -d .swap_files.XXXXXXXXXXXX) &&
tmp_dir2=$(TMPDIR=$(dirname -- "$2") mktemp -d .swap_files.XXXXXXXXXXXX) &&
mv -f -- "$1" "$tmp_dir1/" &&
mv -f -- "$2" "$tmp_dir2/" &&
mv -f -- "$tmp_dir1/"* "$1" &&
mv -f -- "$tmp_dir2/"* "$2" &&
rmdir -- "$tmp_dir1" "$tmp_dir2"
}
Nếu các thư mục tạm thời .swap_files.????????????
có mặt khi khởi động lại, điều đó có nghĩa là việc hoán đổi tập tin bị gián đoạn do mất điện. Xin lưu ý rằng có thể một trong các tệp đã được chuyển vào vị trí còn tệp kia thì không, vì vậy mã ở đây không quan tâm đến tất cả các trường hợp, nó phụ thuộc vào loại phục hồi bạn muốn.
Các hạt nhân Linux hiện đại (kể từ 3.15, được phát hành lại vào tháng 6 năm 2014) có một cuộc gọi hệ thống để trao đổi các tệp : renameat2(…, RENAME_EXCHANGE)
. Tuy nhiên, dường như không có tiện ích dòng lệnh phổ biến nào cho nó. Ngay cả hỗ trợ glibc chỉ được thêm vào gần đây ( 2.28 , được phát hành vào tháng 8 năm 2018).