Có chuyển hướng đầu ra đến một tập tin áp dụng một khóa trên tập tin?


30

Nếu tôi có một lệnh

$ ./script >> file.log

được gọi hai lần, với cuộc gọi thứ hai xảy ra trước khi cuộc gọi đầu tiên kết thúc, chuyện gì xảy ra?

Cuộc gọi đầu tiên có được khóa độc quyền trên tệp đầu ra không? Nếu vậy, tập lệnh thứ hai có bị lỗi khi cố gắng viết hay trình bao không chấp nhận đầu ra (cho phép tập lệnh kết thúc) và đưa ra lỗi không?

Hoặc các tập tin nhật ký được viết đến hai lần?


1
Tôi không biết bất kỳ hệ thống nào sẽ khóa tệp theo mặc định. Điều có nhiều khả năng là hai chương trình sẽ kết thúc xen kẽ các bài viết của chúng, vì cả hai chương trình sẽ ở chế độ chắp thêm. Kết quả sẽ khá khó lường. Thay vì "xin chào thế giới", bạn có thể nhận được "hweolrllod".
jw013

Câu trả lời:


18

Vì bạn đang sử dụng >>, có nghĩa là nối thêm, mỗi dòng đầu ra từ mỗi phiên bản sẽ được nối theo thứ tự xảy ra.

Nếu đầu ra tập lệnh của bạn in 1\nqua 5\nvới độ trễ một giây giữa mỗi và trường hợp hai được bắt đầu 2,5 giây sau, bạn sẽ nhận được điều này:

1
2
1
3
2
4
3
5
4
5

Vì vậy, để trả lời câu hỏi của bạn: Không.


23

Hệ thống Unix bằng và lớn tránh các khóa bắt buộc. Có một vài trường hợp kernel sẽ khóa một tệp chống lại sửa đổi bởi các chương trình người dùng, nhưng không phải nếu nó chỉ được viết bởi một chương trình khác. Không có hệ thống unix nào sẽ khóa một tập tin vì một chương trình đang ghi vào nó.

Nếu bạn muốn các phiên bản đồng thời của tập lệnh của bạn không giẫm lên các ngón chân của nhau, bạn cần sử dụng một cơ chế khóa rõ ràng, chẳng hạn như .flock lockfile

Khi bạn mở một tệp để nối thêm, >>mỗi chương trình được đảm bảo luôn luôn ghi vào cuối tệp. Vì vậy, đầu ra của nhiều trường hợp sẽ không bao giờ ghi đè lên nhau và nếu họ lần lượt viết, đầu ra của chúng sẽ theo thứ tự như ghi.

Điều tồi tệ có thể xảy ra là nếu một trong những trường hợp viết một số lượng đầu ra và mong đợi chúng xuất hiện cùng nhau. Giữa các công tố viên được viết bởi một trường hợp, các trường hợp khác có thể thực hiện việc viết riêng của họ. Ví dụ, nếu phiên bản 1 ghi foo, thì phiên bản 2 ghi hellovà chỉ sau đó phiên bản 2 ghi barthì tệp sẽ chứa foohellobar.

Một quá trình ghi hiệu quả vào tập tin khi nó gọi cuộc gọi writehệ thống. Một cuộc gọi đến writelà nguyên tử: mỗi cuộc gọi để writeviết một chuỗi byte sẽ không bị gián đoạn bởi các chương trình khác. Thường có một giới hạn về số lượng dữ liệu mà một cuộc gọi writesẽ ghi một cách hiệu quả: đối với kích thước lớn hơn, chỉ phần đầu của dữ liệu được ghi và ứng dụng phải gọi writelại. Hơn nữa, nhiều chương trình thực hiện đệm: họ tích lũy dữ liệu trong một vùng nhớ, sau đó ghi dữ liệu này ra thành một đoạn. Một số chương trình xóa bộ đệm đầu ra sau một dòng hoàn chỉnh hoặc phân tách có ý nghĩa khác. Với các chương trình như vậy, bạn có thể mong đợi toàn bộ dòng không bị gián đoạn, miễn là chúng không quá dài (lên đến vài kilobyte; điều này phụ thuộc vào HĐH). Nếu chương trình không tuôn ra tại các điểm có ý nghĩa, nhưng chỉ dựa trên kích thước bộ đệm, bạn có thể thấy một cái gì đó như 4kB từ một thể hiện, sau đó là 4kB từ một thể hiện khác, sau đó lại là 4kB từ phiên bản đầu tiên, v.v.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.