"Awasi" output dari suatu perintah sampai string tertentu diamati dan kemudian keluar


29

Saya mencari cara untuk secara sistematis menonton output dari suatu perintah sampai string tertentu diamati dan kemudian keluar. Ini sangat mirip dengan pertanyaan ini , tetapi alih-alih membuntuti file, saya ingin 'membuntuti' sebuah perintah.

Sesuatu seperti:

tonton -n1 my_cmd | grep -m 1 "String Im Looking For"

(Tapi ini tidak berhasil untukku.)

UPDATE: Saya perlu mengklarifikasi bahwa 'my_cmd' tidak terus-menerus menampilkan teks tetapi perlu berulang kali dipanggil sampai string ditemukan (itulah sebabnya saya memikirkan perintah 'watch'). Dalam hal ini, 'my_cmd' seperti banyak perintah unix lainnya seperti: ps, ls, lsof, last, dll.


Saya akan berpikir itu mungkin untuk tail -fkeluaran program sama seperti file ... Apakah saya salah?
Joanis

@ Joanis. Anda benar, tetapi dalam kasus saya 'my_cmd' tidak terus-menerus menghasilkan output dan harus berulang kali dipanggil (seperti kebanyakan perintah: ps, ls, lsof, dll)
gdw2

Jawaban:


41

Gunakan satu lingkaran:

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

Alih-alih :, Anda dapat menggunakan sleep 1(atau 0,2) untuk mempermudah CPU.

Loop berjalan sampai grep menemukan string di output perintah. -m 1berarti "satu kecocokan sudah cukup", yaitu grep berhenti mencari setelah menemukan kecocokan pertama.

Anda juga dapat menggunakan grep -qyang juga berhenti setelah menemukan kecocokan pertama, tetapi tanpa mencetak baris yang cocok.


penjelasan tentang perintah ini akan dihargai.
Mark W

@ MarkW: Diperbarui.
choroba

orang lain yang menyebutkan grep -qopsi lain. grep berhenti setelah menemukan string.
Sun

perhatikan bahwa perintah ini akan berulang kali menjalankan perintah tersebut, yang mungkin atau mungkin tidak diinginkan.
adrien

1
@ A__: Ini diinginkan, seperti yang dinyatakan dalam OP di bawah "Perbarui".
choroba

11
watch -e "! my_cmd | grep -m 1 \"String Im Looking For\""
  • ! meniadakan kode keluar dari pipa perintah
  • grep -m 1 keluar ketika string ditemukan
  • watch -e kembali jika ada kesalahan yang terjadi

Tapi ini bisa ditingkatkan untuk benar-benar menampilkan garis yang cocok, yang dibuang sejauh ini.


Terima kasih atas penjelasan terperinci, tetapi tidak berhasil untuk saya. watchPerintah saya (CentOS) tidak memiliki -ebendera (yang seharusnya tidak terlalu penting). Lebih penting lagi, ketika senar ditemukan, arloji terus berjalan dan tidak keluar. Tampaknya saat grep -mkeluar, ia hanya keluar membunuh my_cmd, tetapi tidak watch.
gdw2

Tidak, tidak masalah !, bendera "-e" adalah untuk meninggalkan jam tangan ketika perintah memiliki kode kesalahan yang berbeda dari 0. Karena jam tangan yang tidak hadir akan melanjutkan pada platform Anda. Bagaimanapun, baik untuk diketahui, pada instalasi Ubuntu 11.10 saya semuanya baik-baik saja. Saya juga terkadang bermasalah dengan Mac OSX mengenai alat commandline yang sangat ketinggalan jaman dan saya menggunakan port mac sejauh ini untuk mendapatkan lebih banyak perangkat lunak saat ini.
matematika

Ini berhenti jika pola ditemukan, tetapi tidak menunjukkan output apa pun sampai itu terjadi
Tandai

Anda dapat mempekerjakan teeuntuk itu, tetapi ini memperkenalkan baris baru yang menyesatkan, saya tidak tahu bagaimana cara mengelak sekarang:watch -n1 -e "! date | tee /dev/tty | grep --color -m 1 \"17\""
matematika

Ya, ini tidak berhasil untuk saya. watchpatuh berhenti menonton ketika string ditemukan, tetapi itu tidak benar-benar keluar sampai Anda menekan tombol. Sangat dekat.
mlissner

8

Bagi mereka yang memiliki program yang terus menulis ke stdout, semua yang perlu Anda lakukan adalah pipa untuk menangkap dengan opsi 'pertandingan tunggal'. Setelah grep menemukan string yang cocok, itu akan keluar, yang menutup stdout pada proses yang sedang disalurkan ke grep. Acara ini secara alami harus menyebabkan program untuk keluar dengan anggun selama proses menulis lagi .

Apa yang akan terjadi adalah bahwa proses akan menerima SIGPIPE ketika mencoba menulis ke stdout tertutup setelah grep keluar. Berikut ini adalah contoh dengan ping, yang sebaliknya akan berjalan tanpa batas:

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

Perintah ini akan cocok dengan 'pong' pertama yang berhasil, dan kemudian keluar saat berikutnya pingmencoba menulis ke stdout.


Namun,

Tidak selalu dijamin bahwa proses akan menulis ke stdout lagi dan karena itu mungkin tidak menyebabkan SIGPIPE dinaikkan (misalnya, ini bisa terjadi ketika tailing file log). Solusi terbaik yang berhasil saya buat untuk skenario ini melibatkan penulisan ke file; beri komentar jika Anda pikir Anda dapat meningkatkan:

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

Hancurkan ini:

  1. tail -f log_file & echo $! > pid- mengekor file, melampirkan proses ke latar belakang, dan menyimpan PID ( $!) ke file. Saya mencoba mengekspor PID ke variabel, tetapi sepertinya ada kondisi ras antara sini dan ketika PID digunakan lagi.
  2. { ... ;}- kelompokkan perintah-perintah ini bersama-sama sehingga kita dapat menyalurkan output ke grep sambil menjaga konteks saat ini (membantu ketika menyimpan dan menggunakan kembali variabel, tetapi tidak dapat membuat bagian itu berfungsi)
  3. | - pipa sisi kiri stdout ke sisi kanan stdin
  4. grep -m1 "find_me" - temukan string target
  5. && kill -9 $(cat pid)- force kill (SIGKILL) tailproses setelah grep keluar setelah menemukan string yang cocok
  6. && rm pid - hapus file yang kami buat

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

Jika tailtidak mendukung +1fsintaks, coba tail -f -n +1. (The -n +1menyuruhnya untuk memulai di awal; tail -fsecara default dimulai dengan 10 baris terakhir output.)


Silakan lihat pembaruan saya untuk pertanyaan.
gdw2

0

Tambahkan hasil panggilan program Anda ke file. Lalu tail -ffile itu. Dengan begitu itu seharusnya bekerja ... Saya harap.

Ketika Anda memulai kembali panggilan program itu, Anda harus menghapus file atau menambahkan omong kosong hanya agar tidak cocok lagi dengan apa yang Anda cari.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.