Tại sao chuyển hướng đầu ra sed vào cùng một tệp đầu vào làm cho máy của tôi không phản hồi?


13

Tôi đã cố gắng sedthay thế một số từ khóa trong một tệp lớn (100 MB). Tôi không biết về -itùy chọn (tại chỗ), vì vậy nỗ lực đầu tiên của tôi là chuyển hướng như thế này:

sed 's/original/edited/g' file.log >> file.log

Điều xảy ra sau đó là PC của tôi đã dừng hoạt động, gần như không có đầu vào bàn phím. Tôi đã thử một giao diện điều khiển Ctrl+ Alt+ khác F1nhưng sau khi từ từ nhập tên người dùng, nó cũng tạm dừng. Không có bàn phím, lựa chọn duy nhất của tôi là thiết lập lại phần cứng máy. Sau khi đăng nhập, tôi thấy file.log có dung lượng khoảng 8 GB.

Tôi thực sự muốn hiểu tại sao việc thực thi lệnh đó có thể khiến hệ thống không phản hồi và liệu các cơ chế tồn tại ở cấp hệ thống để kích hoạt cảnh báo và giết quá trình vi phạm?


7
Đây có phải là một máy lõi đơn? Có vẻ như rất kỳ lạ rằng điều này đã khiến một chiếc máy tính hiện đại phải quỳ xuống. Làm đầy đĩa của bạn, vâng. Đã sử dụng hết 100% một trong các lõi của bạn, vâng. Nhưng một vụ tai nạn đầy đủ?
terdon

Có điều gì đặc biệt về tập tin đó không? Nếu đây không phải là vấn đề, bạn có thể đăng nội dung của nó lên pastebin không?
Sergiy Kolodyazhnyy

Ngoài ra, số lượng bộ nhớ của bạn là gì? Bạn có thể cung cấp cho chúng tôi đầu ra của free -h ?
Sergiy Kolodyazhnyy

Tại sao phải sử dụng trình chỉnh sửa luồng ở vị trí đầu tiên khi bạn muốn thay đổi tệp? ex -sc '%s/original/edited/ge|x' file.lognên làm những gì bạn muốn theo cách thành ngữ UNIX mà không có sed -itác dụng phụ.
David Ongaro

Lưu ý rằng ngay cả khi bạn đang thực hiện đúng (theo bất kỳ phương pháp nào mà mọi người đang cung cấp), việc thực hiện loại điều này đối với tệp nhật ký thuộc về một quy trình đang hoạt động có thể rất khó khăn.
Random832

Câu trả lời:


10

Như đã nói, >>nối thêm vào tệp, vì vậy sedlệnh của bạn sẽ ngồi đó đọc các dòng mà nó vừa xuất ra, và sau đó xuất ra thêm một số nữa. Nếu bạn muốn thay thế tệp của mình tại chỗ, >vẫn không hoạt động, nhưng bạn nhận thức được tùy chọn sedcủa mình -i, đây chắc chắn là tùy chọn bạn muốn.

Tuy nhiên, nếu bạn hoàn toàn chắc chắn rằng bạn muốn thêm vào một tệp bạn đang đọc dưới dạng luồng và chỉ muốn thực hiện một bước này, hãy cân nhắc sử dụng spongetừ moreutilsgói;

sed 's/original/edited/g' file.log | sponge >> file.log

spongeđọc từ stdin vào bộ nhớ cho đến khi EOF, sau đó chuyển tất cả nội dung của nó vào thiết bị xuất chuẩn, do đó sedsẽ nhấn vào cuối tệp, dừng đọc nó, đóng nó và sau đó bọt biển sẽ bắt đầu gắn vào nó.


2
spongelà một tiện ích tốt đẹp để biết, nhưng sedđã có một -itùy chọn : -i[SUFFIX], --in-place[=SUFFIX], edit files in place (makes backup if SUFFIX supplied).
Joshua Taylor

@JoshuaTaylor, OP đã sử dụng >>, thay vào đó, thay vì >, thay thế. Cấp, OP đã đề cập cụ thể -itrong bài đăng và có vẻ như trường hợp sử dụng phổ biến hơn nhiều so với trường hợp này, nhưng tôi nghĩ rằng đáng để chỉ ra rằng hoạt động cụ thể mà OP đã đăng là có thể mà không cần quá nhiều, nếu bạn thực sự chắc chắn đó là những gì bạn muốn làm.
ymbirtt

1
Tôi đã đề cập ở đây vì nó là chìa khóa trong câu trả lời được chấp nhận . Điều đó nói rằng, tôi thực sự hạnh phúc để tìm hiểu về miếng bọt biển ; nó là một công cụ mới cho hộp công cụ của tôi và xứng đáng là một upvote chỉ cho điều đó.
Joshua Taylor

1
Ah! Tôi hiểu rồi. Tôi sẽ điều chỉnh câu trả lời của mình để làm cho nó rõ ràng hơn một chút. Ngoài ra, nếu bạn thích sponge, hãy xem vipe. moreutilschỉ là một gói ma thuật chứa đầy những thứ bạn không bao giờ biết bạn cần
ymbirtt

18

sedLệnh của bạn đã cố đọc tệp mà nó đang nối vào. Nó sẽ không bao giờ đạt đến End-Of-File, nhưng sẽ ngốn rất nhiều thời gian của CPU. Đó là lý do tại sao ^ C (quá trình hiện tại bị gián đoạn) được phát minh.


Tôi không nghĩ ^ C là một lựa chọn ở đó ... nó đã đi đến HALT, tức là không có con trỏ nhấp nháy, bị mắc kẹt!
EKons

18

Việc quay lại tập tin bạn đọc không phải là một ý tưởng hay, vì bạn sẽ kết thúc với một tập tin ngày càng phát triển. Nếu bạn thực sự muốn ghi lại vào tập tin, bạn nên sử dụng -icờ:

sed -i 's/original/edited/g' file.log

hoặc nếu bạn muốn nó tạo bản sao lưu trước khi thực hiện các thay đổi, bạn có thể thêm hậu tố tệp vào -icờ:

sed -i.bak 's/original/edited/g' file.log

Điều này sẽ tạo ra một tệp được gọi file.log.bakvà sau đó thực hiện các thay đổi, những gì bạn đã làm ở đó bằng cách thêm vào tệp bạn đang đọc từ chúng tôi gọi trong lập trình viên tạo ra một cuộc đua dữ liệu, trong đó các quy trình khác nhau chạy cho cùng một nguồn dữ liệu là đầu vào hoặc đầu ra . Đây cũng là lý do tại sao máy của bạn dừng lại.


1
Tôi ngạc nhiên đây là câu trả lời được chấp nhận, bởi vì nó thậm chí không giải quyết được câu hỏi của OP"I really would like to understand why the execution of that command was able to make the system so unresponsive, and if mechanisms exist at the system level to trigger alerts and kill the offending process?"
Steve

@Steve Vì lý do tại sao nó dừng lại, tôi đã giải quyết, nhưng đối với phần thứ hai, bạn đã đúng. Tôi đã không giải quyết điều đó bởi vì tôi không biết câu trả lời cho điều này. Chúng tôi đã thử nghiệm lệnh sau khi thảo luận rộng rãi và cho kết quả hoàn toàn khác nhau trên các máy và hệ điều hành khác nhau. Ví dụ: Trên một máy có vòm, nó chỉ cho phép tệp phát triển mãi mãi, nhưng không khiến máy không phản hồi. Trên máy Ubuntu của tôi, tôi đã nhận được kết quả giống như người hỏi mà không có cơ hội giết quá trình. Một máy thứ hai kiểm tra tương tự trong một máy ảo Ubuntu cũng bị dừng lại.
Videonauth

Một stracetrong toàn bộ quá trình ở phía bên kia đã không tái tạo kết quả và điều này trên máy của tôi và trên máy của một người dùng khác. Chắc chắn có cơ chế mà bạn có thể giết các ứng dụng không phản hồi, nhưng nếu máy của bạn không phản hồi, bạn chỉ còn lại một tùy chọn, đặt lại nó. Tôi vẫn đang thử nghiệm về điều này và trước khi tôi không hiểu đầy đủ những gì gây ra hành vi được mô tả, tôi không thể giải quyết phần này của câu hỏi.
Videonauth

Đây có thể là một sự khác biệt trong cấu hình kernel, giống như một bộ lập lịch khác ưu tiên IO hoặc sự khác biệt trong trình điều khiển hệ thống tập tin / đĩa giữa các hệ thống. Thật tốt khi thấy cuộc điều tra mà các bạn đã làm, đó là thông tin tốt.
Steve

Nếu bạn quan tâm đến một điểm dữ liệu khác; Tôi đã thử điều này trên máy CentOS với một tệp khá nhỏ và nó đã làm chính xác như giải pháp bọt biển của tôi dưới đây. Tôi tưởng tượng rằng đối với một tập tin nhỏ sedsẽ đệm toàn bộ vào bộ nhớ và sau đó đóng nó, thay vì giữ tay cầm. Với tệp ~ 100 MB, như trong OP, nó tăng trưởng vô thời hạn nhưng không làm hỏng máy.
ymbirtt
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.