Xem đồng hồ trên đầu ra của một lệnh cho đến khi một chuỗi cụ thể được quan sát và sau đó thoát


29

Tôi đang tìm cách để lập trình theo dõi đầu ra của lệnh cho đến khi một chuỗi cụ thể được quan sát và sau đó thoát. Điều này rất giống với câu hỏi này , nhưng thay vì theo đuôi một tệp, tôi muốn 'đuôi' một lệnh.

Cái gì đó như:

xem -n1 my_cmd | grep -m 1 "Chuỗi tôi đang tìm kiếm"

(Nhưng điều này không làm việc cho tôi.)

CẬP NHẬT: Tôi cần làm rõ rằng 'my_cmd' không liên tục xuất văn bản mà cần được gọi lại nhiều lần cho đến khi tìm thấy chuỗi (đó là lý do tại sao tôi nghĩ đến lệnh 'xem'). Về mặt này, 'my_cmd' giống như nhiều lệnh unix khác như: ps, ls, lsof, last, v.v.


Tôi đã có thể nghĩ rằng nó có thể tail -flà một đầu ra chương trình cũng như một tập tin ... Tôi có sai không?
Joanis

@Jananis. Bạn đúng, nhưng trong trường hợp của tôi, 'my_cmd' không liên tục tạo đầu ra và phải được gọi liên tục (giống như hầu hết các lệnh: ps, ls, lsof, v.v.)
gdw2

Câu trả lời:


41

Sử dụng một vòng lặp:

until my_cmd | grep -m 1 "String Im Looking For"; do : ; done

Thay vì :, bạn có thể sử dụng sleep 1(hoặc 0,2) để giảm bớt CPU.

Vòng lặp chạy cho đến khi grep tìm thấy chuỗi trong đầu ra của lệnh. -m 1có nghĩa là "một trận đấu là đủ", tức là grep dừng tìm kiếm sau khi tìm thấy trận đấu đầu tiên.

Bạn cũng có thể sử dụng grep -qcũng thoát sau khi tìm thấy kết quả khớp đầu tiên, nhưng không in dòng phù hợp.


một lời giải thích về lệnh này sẽ được đánh giá cao.
Đánh dấu W

@MarkW: Đã cập nhật.
choroba

một người khác đề cập đến grep -qđó là một lựa chọn khác. grep thoát sau khi tìm chuỗi.
CN

lưu ý rằng lệnh này sẽ liên tục chạy lệnh trong câu hỏi, điều này có thể hoặc không thể mong muốn.
adrien

1
@A__: Đó là mong muốn, như đã nêu trong OP trong phần "Cập nhật".
choroba

11
watch -e "! my_cmd | grep -m 1 \"String Im Looking For\""
  • ! phủ nhận mã thoát của đường ống lệnh
  • grep -m 1 thoát khi tìm thấy chuỗi
  • watch -e trả về nếu có lỗi xảy ra

Nhưng điều này có thể được cải thiện để thực sự hiển thị dòng phù hợp, được ném đi cho đến nay.


Cảm ơn đã giải thích chi tiết, nhưng nó không làm việc cho tôi. watchLệnh của tôi (CentOS) không có -ecờ (điều này không thực sự quan trọng). Quan trọng hơn, mặc dù, khi chuỗi được tìm thấy, đồng hồ tiếp tục chạy và không thoát. Có vẻ như khi grep -mthoát ra, nó chỉ thoát được my_cmd, nhưng không watch.
gdw2

Không, có vấn đề gì không!, Cờ "-e" được dùng để rời khỏi đồng hồ khi lệnh có mã lỗi khác 0. Vì đồng hồ không có mặt của nó sắp tiếp tục trên nền tảng của bạn. Nhưng dù sao, thật tốt khi biết, trên bản cài đặt Ubuntu 11.10 của tôi, mọi thứ đều ổn. Đôi khi tôi cũng gặp rắc rối với Mac OSX về các công cụ dòng lệnh rất lỗi thời và cho đến nay tôi đang sử dụng các cổng mac để có thêm phần mềm hiện tại.
toán

Điều này dừng lại nếu mẫu được tìm thấy, nhưng nó không hiển thị bất kỳ đầu ra nào cho đến khi điều đó xảy ra
Đánh dấu

Bạn có thể sử dụng teecho điều đó, nhưng điều này giới thiệu một dòng mới gây hiểu lầm, tôi không biết cách phá vỡ ngay bây giờ:watch -n1 -e "! date | tee /dev/tty | grep --color -m 1 \"17\""
toán

Vâng, điều này đã không làm việc cho tôi. watchNghiêm túc dừng xem khi tìm thấy chuỗi, nhưng nó không thực sự thoát cho đến khi bạn nhấn một phím. Thật gần gũi.
mlissner

8

Đối với những người có một chương trình liên tục viết lên thiết bị xuất chuẩn, tất cả những gì bạn cần làm là chuyển nó thành grep với tùy chọn 'một trận đấu'. Khi grep tìm thấy chuỗi phù hợp, nó sẽ thoát, nó sẽ đóng thiết bị xuất chuẩn trên tiến trình đang được dẫn đến grep. Sự kiện này tự nhiên sẽ khiến chương trình thoát ra một cách duyên dáng miễn là quá trình viết lại .

Điều gì sẽ xảy ra là quá trình sẽ nhận được SIGPIPE khi nó cố gắng ghi vào thiết bị xuất chuẩn sau khi grep đã thoát. Dưới đây là một ví dụ với ping, nếu không sẽ chạy vô thời hạn:

$ ping superuser.com | grep -m 1 "icmp_seq"

Lệnh này sẽ khớp với 'pong' thành công đầu tiên, và sau đó thoát ra trong lần tiếp theo pingcố gắng viết vào thiết bị xuất chuẩn.


Tuy nhiên,

Không phải lúc nào cũng đảm bảo rằng quy trình sẽ ghi vào thiết bị xuất chuẩn một lần nữa và do đó có thể không khiến SIGPIPE được nâng lên (ví dụ: điều này có thể xảy ra khi nối đuôi tệp nhật ký). Giải pháp tốt nhất tôi đã quản lý để đưa ra cho kịch bản này liên quan đến việc ghi vào một tệp; hãy bình luận nếu bạn nghĩ rằng bạn có thể cải thiện:

$ { tail -f log_file & echo $! > pid; } | { grep -m1 "find_me" && kill -9 $(cat pid) && rm pid; }

Phá vỡ điều này:

  1. tail -f log_file & echo $! > pid- đuôi một tệp, đính kèm tiến trình vào nền và lưu PID ( $!) vào tệp. Thay vào đó, tôi đã thử xuất PID thành một biến, nhưng có vẻ như có một điều kiện chạy đua giữa đây và khi PID được sử dụng lại.
  2. { ... ;}- nhóm các lệnh này lại với nhau để chúng ta có thể dẫn đầu ra thành grep trong khi vẫn giữ bối cảnh hiện tại (giúp khi lưu và sử dụng lại các biến, nhưng không thể làm cho phần đó hoạt động)
  3. | - ống bên trái stdout sang phải stdin bên phải
  4. grep -m1 "find_me" - tìm chuỗi mục tiêu
  5. && kill -9 $(cat pid)- lực lượng giết (SIGKILL) tailquá trình sau khi grep thoát khi tìm thấy chuỗi phù hợp
  6. && rm pid - xóa tệp chúng tôi đã tạo

0
my_cmd | tail +1f | sed '/String Im Looking For/q'

Nếu tailkhông hỗ trợ +1fcú pháp, hãy thử tail -f -n +1. (Việc -n +1bảo nó bắt đầu từ đầu; tail -ftheo mặc định bắt đầu với 10 dòng đầu ra cuối cùng.)


Xin vui lòng xem cập nhật của tôi cho câu hỏi.
gdw2

0

Nối kết quả của các cuộc gọi chương trình của bạn vào một tệp. Rồi tail -ftập tin đó. Theo cách đó nó sẽ hoạt động ... Tôi hy vọng.

Khi bạn khởi động lại việc gọi chương trình đó, bạn sẽ phải xóa tệp hoặc nối một số từ vô nghĩa vào nó để nó không khớp lại ngay lập tức những gì bạn đang tìm kiếm.

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.