Chuyển đến nội dung chính (Skip to content)
Mục lục bài viết
Linux Essentials

Linux Essentials 2.4: Tạo, di chuyển và xóa Tệp

Linux Essentials 2.4: Tạo, di chuyển và xóa Tệp

Thực hành thao tác tệp Linux trong thư mục riêng: tạo, sao chép, đổi tên và xóa; kiểm tra nguồn, đích, ghi đè và kết quả sau từng bước thay đổi dữ liệu.

Tạo, sao chép, di chuyển và xóa là bốn thay đổi khác nhau

Bạn muốn gửi một bản ghi chú cho đồng nghiệp nhưng lại di chuyển tệp gốc sang nơi khác. Một script vẫn trỏ đến vị trí cũ bắt đầu báo lỗi, dù nội dung không mất. Sự cố này cho thấy cần hiểu thao tác ảnh hưởng tên, vị trí và số bản dữ liệu thế nào. Với lệnh shell, một ký tự hoặc một thư mục đích có thể thay đổi phạm vi nhiều hơn bạn nghĩ.

Bài thuộc mục tiêu 2.4 của Linux Essentials 010-160, liên hệ 012.4 của 010-200. Mốc biên tập: 23/10/2026. Lab dùng Bash và các tiện ích coreutils trên Ubuntu 26.04 LTS, chỉ thay đổi dữ liệu tự tạo dưới một thư mục tạm. Bạn sẽ kiểm tra đích trước khi tạo, copy, move và delete; chưa dùng thao tác đệ quy lên thư mục thật của người dùng.

Image Ubuntu 26.04.1 đã kiểm tra có ls thuộc uutils 0.10.0, còn cp, mv và rm báo GNU coreutils 9.7. Một image có thể kết hợp nhiều implementation; đối chiếu --version và --help của đúng lệnh, không suy từ ls sang toàn bộ công cụ. GNU cp là nguồn cho phần sao chép; tài liệu phải khớp bản cài khi dùng tùy chọn nâng cao.

Dựng một nơi thử mới, không trộn với dữ liệu cũ

Khối dưới tạo thư mục mới và hai nhánh inbox, sent. mktemp -d trả một tên chưa dùng theo cơ chế của hệ thống; giữ biến lpi_files trong cùng phiên shell. Dấu > ghi nội dung vào tệp dưới thư mục mới. Khi áp dụng ở nơi khác, nó có thể cắt ngắn tệp đã tồn tại, vì vậy không thay đích bằng tài liệu công việc.

lpi_files=$(mktemp -d)
mkdir -p -- "$lpi_files/inbox" "$lpi_files/sent"
printf '%s\n' 'Ghi chú giả lập cho bài học' > "$lpi_files/inbox/note.txt"
printf '%s\n' "$lpi_files"
ls -l -- "$lpi_files/inbox" "$lpi_files/sent"

Bạn dự kiến có một tệp trong inbox và sent chưa có tệp. Nếu không thấy trạng thái này, dừng kiểm tra thông báo và đường dẫn trước khi chạy tiếp. Không giải quyết một biến rỗng bằng cách bỏ dấu nháy hoặc đổi đích thành /. Bài thực hành không có bước yêu cầu nâng quyền.

Trước mỗi thay đổi, đọc cả nguồn và đích. Một đích đã là thư mục có thể khiến cp hoặc mv đặt nguồn vào bên trong, khác với việc tạo đúng tên tệp mới. Các phần dưới dùng tên rõ ràng và thư mục lab đã kiểm soát để quan sát từng hành vi.

mkdir tạo thư mục, touch không phải công cụ ghi nội dung

mkdir tạo thư mục theo yêu cầu. Với -p, GNU mkdir có thể tạo các thành phần cha còn thiếu và không báo lỗi chỉ vì một thư mục đã tồn tại phù hợp. Điều đó hữu ích cho cây lab nhưng không chứng minh đường dẫn trỏ đúng nơi bạn muốn. Với một đường dẫn sai biến, -p cũng có thể tạo một cây ngoài ý định nếu tài khoản có quyền.

touch thường được biết như cách tạo tệp rỗng nếu tên chưa tồn tại. Với tệp đã có, nó có thể cập nhật timestamp mà không thay nội dung. Thời gian tệp thay đổi có thể ảnh hưởng công cụ theo dõi hoặc build, nên “không sửa chữ nào” không đồng nghĩa hoàn toàn không đổi trạng thái.

touch -- "$lpi_files/inbox/empty.txt"
ls -l -- "$lpi_files/inbox/empty.txt"

Kết quả dự kiến là một tệp dung lượng 0 trong lab mới. Không dùng touch để tạo tệp cấu hình rỗng rồi kết luận dịch vụ đã được cấu hình. Chương trình đọc tệp còn có cú pháp và mặc định riêng. Bài này chỉ học quan hệ tên, thư mục và thao tác tệp.

Kiểm tra nguồn, đích và tác động trước mỗi thay đổi dữ liệu.
Hình 1. Kiểm tra nguồn, đích và tác động trước mỗi thay đổi dữ liệu. Mở hình để xem chi tiết.

Tên có phân biệt chữ hoa/chữ thường hay không phụ thuộc filesystem và cách mount. Trên filesystem Linux thường dùng, Note.txt và note.txt có thể là hai tên khác. Khi nhận một archive từ hệ khác hoặc dùng shared folder, hãy kiểm tra môi trường đích thay vì áp một kết luận cho mọi ổ. Đổi tên chỉ khác chữ hoa cũng cần xem ứng dụng còn giữ tham chiếu nào.

cp tạo bản dữ liệu, cần kiểm tra khả năng ghi đè

cp sao chép dữ liệu theo tùy chọn và loại đối tượng được chỉ định. Ở ví dụ đơn giản, chúng ta copy một tệp thường sang tên mới trong sent. Sau đó đọc hai tệp để chứng minh nguồn vẫn còn và bản đích có nội dung dự kiến.

cp -i -- "$lpi_files/inbox/note.txt" "$lpi_files/sent/note-copy.txt"
cat "$lpi_files/inbox/note.txt"
cat "$lpi_files/sent/note-copy.txt"

Với cp trong lab, -i yêu cầu hỏi khi thao tác sẽ ghi đè trong trường hợp liên quan. Trong lab mới, đích chưa có nên thường không xuất hiện câu hỏi. Nếu bạn chạy lại và nhận prompt, đọc đường dẫn rồi quyết định theo dữ liệu thực tế. Bài không yêu cầu trả lời yes cho mọi prompt.

Sao chép tệp không mặc định là một bản sao lưu đầy đủ. Quyền, timestamp, symlink, ACL hoặc dữ liệu đặc biệt cần tùy chọn và môi trường phù hợp. Ở mức nhập môn, chỉ kết luận đã có thêm bản nội dung tệp thường như phép kiểm tra. Khi cần sao lưu hệ thống, phải lập yêu cầu phục hồi và kiểm thử riêng.

mv đổi vị trí hoặc tên, nguồn cũ có thể không còn

Di chuyển tệp trong cùng filesystem thường khác việc copy nội dung rồi giữ cả hai tên độc lập. Khi đi qua ranh giới filesystem, implementation có thể phải sao chép rồi loại bỏ nguồn sau khi hoàn tất. Điều quan trọng với người dùng là sau move thành công, các chương trình còn dùng đường dẫn cũ có thể không tìm thấy tệp.

mv -i -- "$lpi_files/sent/note-copy.txt" "$lpi_files/sent/note-sent.txt"
ls -l -- "$lpi_files/sent"
cat "$lpi_files/sent/note-sent.txt"

Trong cây lab, bạn dự kiến thấy note-sent.txt và không còn note-copy.txt. Tệp note.txt ở inbox vẫn tồn tại vì nó là nguồn của lần copy trước, không phải nguồn của lần move này. Hãy giải thích được ba tên đó trước khi xem bài đã đạt. Chỉ nhận một thông báo không lỗi chưa đủ để biết nguồn nào còn giữ.

Move cũng có thể ghi đè tên đích theo điều kiện và tùy chọn. Đừng dùng nó để “dọn gọn” các cấu hình đang được ứng dụng tham chiếu mà chưa biết cách ứng dụng nạp dữ liệu. Đổi tên một tệp log hoặc database trong lúc chương trình chạy có thể có hành vi vượt khỏi ví dụ tệp văn bản này.

Copy tạo thêm bản dữ liệu; move trong ví dụ đổi tên bản đã chọn, giữ nguồn ban đầu.
Hình 2. Copy tạo thêm bản dữ liệu; move trong ví dụ đổi tên bản đã chọn, giữ nguồn ban đầu. Mở hình để xem chi tiết.

Globbing chọn nhiều tên trước khi chương trình chạy

Trong Bash, mẫu như *.txt có thể được mở rộng theo nội dung thư mục trước khi cp hoặc rm nhận đối số. Điều đó có nghĩa phạm vi thay đổi phụ thuộc nơi đứng, tên tệp hiện có và tùy chọn shell. Mẫu không phải một từ khóa “chỉ chọn tệp an toàn”. Nó có thể khớp cả tên không nằm trong ý định của bạn.

printf '[%s]\n' "$lpi_files"/inbox/*.txt

Khối trên chỉ in các tên mà shell truyền, không xóa chúng. Với cây đã tạo, bạn dự kiến thấy note.txt và empty.txt; thứ tự không phải tiêu chí chính của bài. Một mẫu không khớp có thể được giữ nguyên trong cấu hình Bash mặc định. Những tùy chọn như nullglob hoặc failglob làm hành vi khác, nên hãy ghi môi trường khi tái hiện script.

Trong ví dụ có biến thư mục, quote phần biến giữ ranh giới của đường dẫn nền, còn mẫu nằm ngoài quote để được mở rộng có chủ ý. Nếu toàn bộ mẫu được quote, chương trình nhận ký tự * thay vì danh sách do Bash tạo trong trường hợp này. Các cơ chế cụ thể của chương trình sau đó vẫn cần đọc riêng.

Xóa tệp khác chuyển vào thùng rác giao diện

rm trên dòng lệnh thông thường không cung cấp cùng quy trình khôi phục qua Trash của desktop. Lệnh sau xóa đúng tệp rỗng do bài này tạo. Sau khi đồng ý tại prompt, tên tệp bị gỡ khỏi thư mục; bài không bảo đảm có cách phục hồi nội dung bằng giao diện. Kiểm tra biến lpi_files và tên empty.txt trước khi chạy.

ls -l -- "$lpi_files/inbox/empty.txt"
rm -i -- "$lpi_files/inbox/empty.txt"
ls -l -- "$lpi_files/inbox"

Trả lời câu hỏi theo ý định xóa tệp lab đó. Nếu bạn từ chối, tệp vẫn còn và đó là hành vi hợp lệ; ghi kết quả thay vì ép nó khớp ví dụ. Nếu đã đồng ý, listing sau cần cho thấy empty.txt không còn, còn note.txt vẫn giữ. Không thêm -f hoặc -r để bỏ qua một lỗi chưa hiểu.

Các tùy chọn GNU rm có phạm vi cụ thể. Tính năng hỏi trước không thay việc kiểm tra danh sách và đường dẫn. Xóa đệ quy, lỗi biến hoặc đi qua điểm mount có thể có tác động lớn; chúng không phải bước tiếp theo tự động khi rm báo đang gặp thư mục.

rmdir chỉ dùng cho thư mục rỗng trong ví dụ này

Để quan sát rmdir, tạo một thư mục mới không có dữ liệu rồi xóa đúng tên đó. Thao tác này loại thư mục lab vừa tạo. Nếu thư mục có nội dung và rmdir từ chối, hãy xem nội dung bằng lệnh chỉ đọc; bài không yêu cầu chuyển sang rm -rf.

mkdir -- "$lpi_files/empty-dir"
rmdir -- "$lpi_files/empty-dir"
ls -ld -- "$lpi_files"

Vùng lab chính vẫn còn cùng các tệp khác. Bạn có thể giữ nó cho buổi sau. Một quy trình dọn dữ liệu thật cần xác định người sở hữu, thời hạn giữ và bản phục hồi, không chỉ chọn lệnh xóa chạy nhanh nhất.

Tự kiểm tra bằng trạng thái trước và sau

Câu hỏi 1: Sau chuỗi cp rồi mv trong bài, note.txt ở inbox có còn không? Có, vì mv chỉ tác động bản copy ở sent. Câu hỏi 2: touch trên tệp tồn tại có luôn vô tác động? Không; timestamp có thể thay đổi. Câu hỏi 3: -i có thay thế kiểm tra đường dẫn không? Không; prompt chỉ là một lớp hỗ trợ.

Câu hỏi 4: printf với mẫu *.txt chứng minh điều gì? Nó cho thấy tên được mở rộng trong bối cảnh hiện tại; danh sách có thể thay đổi khi thư mục hoặc shell option đổi. Bạn đạt bài khi mô tả được nguồn, đích và số bản còn lại sau từng thao tác, đồng thời giải thích tác động xóa ngay tại bước thực hiện.

Bài liên quan trong bộ LPI

Tìm hiểu thêm