This page is READ-ONLY. It is generated from the old site.
All timestamps are relative to 2013 (when this page is generated).
If you are looking for TeX support, please go to VietTUG.org

đổi tên tập tin đang mở: Bash version

phiên bản Bash của blog#524
Added by almost 3 years ago  »  Votes: 2/2

Dưới đây là phiên bản Bash (>= 4.0.0). Các câu hỏi ở bài (blog) đổi tên tập tin đang mở có câu trả lời thế nào?

 1 #!/bin/bash
 2 
 3 coproc myproc { cat >> ./test.log ;}
 4 
 5 while :; do
 6   echo -n "." 
 7   echo "... $SECONDS" >&${myproc[1]}
 8   sleep 2
 9 done
10 
11 kill $myproc_PID

Gợi ý: Lưu đoạn mã ở trên với tên test.sh, chuyển đổi quyền thi hành chmod 700 test.sh và thực hiện lệnh. Sau đó, tiến hành đổi tên tập tin test.log thành test2.log y hệt trong bài (blog) đổi tên tập tin đang mở.

Cập nhật: Dưới đây là phiên bản dành cho BourneBash phiên bản bất kỳ

1 #!/bin/sh
2 while :; do
3  echo -n '.' 1>&2
4  echo ".... `date +%S`" 
5  sleep 2
6 done \
7 > test2.log

Comments

Added by bronzeboyvn almost 3 years ago

Chạy thử, thì bronzeboyvn thấy kết quả:

process @[email protected] vẫn chạy tiếp sau khi ta đổi tên. 
process chấm dứt khi ta bấm Ctr+C. Dữ liệu có vẻ không mất mát gì.

Trong script test.sh, có vẻ tên file không quan trọng. bronzeboyvn đoán script chỉ làm việc với inode (i.e. script nắm inode mà trút dữ liệu vào).
Có thể ví dụ như bronzeboyvn cứ 2 ngày tới nhà anh z ném đá. Anh z có thay đổi biển số nhà, thì cũng vô dụng. Vì bronzeboyvn không cần biết số nhà, mà cứ tới đúng địa điểm đó mà ném. inode ~ vị trí file trong ổ cứng ~ vi trí nhà trong không gian. Tên file ~ biển số nhà.

Added by almost 3 years ago

Thật ra bài toán này xuất phát từ một chương trình C, nhưng mình muốn triển khai lại trong các ngôn ngữ như PHPBash/Bourne để kiểm tra. Bạn bronzeboyvn có thể thử và kiểm tra trong C (và tài liệu của C chắc đề cập tới vấn đề này kỹ hơn :P).

Nếu chỉ làm việc với inode, thì liệu có thể dùng inode để phá không nhỉ (không cần thông qua tên tập tin)?

Added by bronzeboyvn almost 3 years ago

Mình (user) làm việc với tên file, kernel làm việc với inode.

có thể dùng inode để phá không nhỉ

bronzeboyvn nghĩ mình không có cửa đụng tới inode để mà phá.

Added by bronzeboyvn almost 3 years ago

Chính xác là process tesh.sh làm việc với inode. Khi tesh.sh đang chạy, bronzeboyvn thực thi các lệnh sau:

mv test.log test2.log
echo "hello" >> test.log

Khi Ctr+C kết thúc test.sh, trong test.log chỉ có từ "hello", còn trong test2.log là những số (giây) chẵn.
Chính vì script nắm inode, nên lúc sau bronzeboyvn tạo file test.log, file này có inode khác. Script không ghi gì vào test.log "mới".

Added by almost 3 years ago

Cảm ơn bronzeboyvn.

Mình thật sự không hiểu lắm về cơ chế, nhưng mình đoán rằng mọi sự nằm trong mã nguồn của nhân (fs/open.c, mình biết cái này nhưng chưa tìm ra chỗ để đọc). Theo mình đoán, khi yêu cầu mở một tập tin để ghi vào, open sẽ dùng tên tập tin để tìm ra số inode, và từ đó trực tiếp làm việc với inode luôn, tên tập tin không còn ảnh hưởng nữa. Khi ta thay đổi tên tập tin thì chỉ là thay đổi thông tin meta của inode, do đó, tiến trình đang ghi vào tập tin không hề biết. Xem sự khác biệt về access timemodify time ở bài linux: thời gian tập tin được tạo ra.

Theo mình thì không chỉ việc mở, mà việc đọc, ghi thêm,... cũng có hiệu ứng tương tự, và ngôn ngữ sẽ không quan trọng nữa (PHP, Ruby, Bash, C,... đều như nhau cả.) [Cần phải kiểm tra điều này.]

Có thể làm việc trực tiếp với inode hay không thì vẫn còn là một câu hỏi mở. Trước đây vài năm, ở http://vnlinux.org/ (nay đã chết) có bài hướng dẫn rất chi tiết phục hồi tập tin sau khi xóa: bí quyết nằm ở chỗ inode cùng các thông tin của nó vẫn tồn tại sau khi ta xóa một tập tin (vô ý). Nếu tìm trên google chắc sẽ ra bài hướng dẫn kiểu này.

Còn ứng dụng của việc này thì chắc là nhiều :) Mình sẽ viết một bài ở Freesoft sau (vì nó liên quan tới kỹ thuật hệ thống chứ không phải lập trình, không tiện để ở đây.)

Ref.: Hình vẽ lấy từ http://en.wikipedia.org/wiki/Inode_pointer_structure