Có một công cụ để tự động chuyển hướng đầu ra sang một tệp mới theo yêu cầu


8

Tôi hiện đang chuyển hướng đầu ra của một công cụ giám sát sang một tệp, tuy nhiên điều tôi muốn làm là chuyển hướng đầu ra này sang một tệp mới theo yêu cầu của tôi (sử dụng phím bấm), mà không dừng công cụ nói trên.

Cái gì đó như

monitor_program | handle_stdout

Nơi handle_stdoutcho phép tôi xác định một tệp mới, nơi đặt nhật ký tại một số điểm nhất định.

Tôi biết tôi có thể dễ dàng viết nó, nhưng tôi tự hỏi liệu có công cụ nào đã cho phép điều này không.


Bạn có thể có thể chạy logrotatevới một tệp cấu hình tùy chỉnh theo cách thủ công, tùy thuộc vào hành vi của Monitor_program của bạn, nhưng điều đó hơi khó tin.
Ulrich Schwarz

Có vẻ như chỉnh sửa của bạn thực sự là một câu trả lời cho câu hỏi. Trong trường hợp đó, xin vui lòng gửi nó dưới dạng câu trả lời (tự trả lời được khuyến khích!) Và xóa câu trả lời khỏi câu hỏi của bạn.
con mèo

Câu trả lời:


9

Tôi sẽ đề nghị một đường ống được đặt tên.

  1. Tạo một đường ống mkfifo p(gọi nó là bất cứ điều gì bạn muốn, nếu không phải là 'p')

  2. Tạo một tập lệnh "đọc" đọc từ ống và viết bất cứ nơi nào bạn muốn

  3. Yêu cầu chương trình giám sát ghi nhật ký của nó vào đường ống được đặt tên

Đây là tập lệnh đọc mẫu đọc từ một ống có tên 'p' và ghi dữ liệu vào tệp 'mylog' được lập chỉ mục:

#!/bin/sh

INDEX=0

switchlog() {
  read INDEX < newindex
  echo now writing to "mylog.$INDEX"
}

trap switchlog USR1

while :
do
  cat p >> mylog."$INDEX"
done

2
Bạn cũng có thể bẫy tín hiệu (ví dụ USR1) trong tập lệnh đọc làm tín hiệu để chuyển nhật ký.
Jeff Schaller

Đây bắt đầu là thứ tôi cần ... Tuy nhiên, tập lệnh người đọc có thể thay đổi đầu ra dựa trên kebinding của tôi. Và có khả năng yêu cầu tôi sử dụng tên tệp mới (mặc dù đây là tùy chọn, thậm chí có tên nhật ký tuần tự sẽ ổn)
Treviño

Tôi đã chỉnh sửa tập lệnh mẫu để hiển thị ví dụ về chuyển đổi nhật ký với kill -USR1. lặp lại một số mới vào tập tin 'newindex' để nhận.
Jeff Schaller

1
chỉ là một ý tưởng khác - nếu bạn giữ một cửa sổ mở cho tập lệnh "reader" đang chạy, bạn có thể bẫy 'INT' thay vì USR1 và chỉ cần nhấn Control-C trong cửa sổ đó để thông báo cho tên tệp nhật ký mới.
Jeff Schaller

1
Tại sao readprintfthay vì chỉ cat <p >> mylog."$INDEX"?
tự đại diện

7

Dựa trên ý tưởng SIGINT của bạn, ở đây sử dụng SIGQUIT ( Ctrl+\) để bạn vẫn có thể sử dụng Ctrl+Cđể ngăn chặn toàn bộ sự việc:

(trap '' QUIT; monitor_command) | (
   trap : QUIT
   ulimit -c 0 # prevent core dump so SIGQUIT behaves like SIGINT
               # for cat
   n=0; while n=$((n+1)); file=output.$n.log; do
     printf 'Outputting to "%s"\n' "$file"
     cat > "$file"
   done)

Giả định đó catkhông phải là nội dung trong vỏ của bạn (vì vậy nó sẽ bị gián đoạn khi bạn nhấn Ctrl+\).

Lưu ý rằng giống như trong cách tiếp cận của bạn, có khả năng SIGQUIT được gửi không đúng lúc (trong cuộc gọi hệ thống ghi) khiến một số dữ liệu bị mất.


1

Bạn có thể có thể sử dụng lessvà lưu từ đó bằng cách nhập stên tệp bạn muốn lưu vào Enter. Từ Làm thế nào để tôi viết tất cả các dòng từ ít hơn vào một tập tin? .


Thật không may, người dùng không thể sử dụng nhiều tệp nhật ký hơn, khi bạn đã đặt một tệp bạn không thể xác định lại một tệp mới. Ngoài ra, bạn không thể xóa nhật ký một khi được thực hiện. Vì vậy, ... điểm khởi đầu tốt (cảm ơn), nhưng chưa đủ.
Treviño

0

Không biết thêm về "yêu cầu" của bạn, nó không thực sự có thể trả lời. Nếu nó dựa trên kích thước hoặc khoảng cách của tệp, thì rotatelogs (sẽ đi kèm với Apache httpd) sẽ hoạt động.


Xin lỗi, tôi đã không nói điều đó một cách rõ ràng, tôi giả sử một liên kết phím sẽ cho phép thay đổi tên nhật ký.
Treviño

0

Nhờ câu trả lời của Jeff Schaller , tôi đã kết thúc với một thứ như thế này, về cơ bản là những gì tôi cần, hãy gọi nó là reader.sh:

#!/bin/sh

INDEX=0
LOGNAME="$INDEX.log"

switchlog() {
  local custom_name
  read -p "Add log name: " custom_name
  INDEX=$((INDEX+1))
  LOGNAME="$(printf "%03d" $INDEX).$custom_name.log"
  echo now writing to $LOGNAME
}

trap switchlog INT
switchlog

while :
do
  read foo < p
  printf "%s\n" "$foo" >> "$LOGNAME"
done

Sau đó, nó chỉ là về việc tạo ra một ống tên với mkfifo p, và cách sử dụng hai thiết bị đầu cuối nơi monitor_program > preader.shđang chạy. Sau đó tôi có thể dừng trình đọc để thiết lập nhật ký mới bằng cách sử dụng Ctrl+ Cvà nhập tên mới. Ctrl+ Z, như thường lệ sau đó dừng lại và giết nó.

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.