Perintah apa yang akan saya gunakan untuk membuat dua proses anak secara serial?

8

Saya ingin menelurkan dua proses anak, tetapi tunggu sampai yang pertama mencapai titik tertentu dalam pelaksanaannya (yang dapat ditentukan dengan memeriksa stdout) sebelum menelurkan yang kedua. Saya tidak yakin perintah unix mana yang akan terlibat dalam mencapai hal ini, dan mengalami kesulitan menemukan sesuatu melalui google karena sifat nama perintah unix yang singkat dan terkadang samar.

Saya tidak mencari solusi untuk masalah spesifik yang saya coba selesaikan (meskipun ada petunjuk tambahan akan dihargai), saya terutama khawatir dengan mengetahui perintah unix mana yang ingin saya cari dan pelajari untuk digunakan.

w.brian
sumber
Apakah Anda terbuka untuk menggunakan Python?
xrisk
3
Tanpa mengetahui bagaimana Anda menentukan "titik tertentu dalam pelaksanaannya", ini sangat kabur.
muru
@muru diedit untuk menjelaskan
w.brian
Jadi Anda sebenarnya membutuhkan 3 proses. 1. berjalan, menciptakan output; 2. memantau output 1, dan pada titik tertentu dimulai 3. Ini adalah info yang cukup untuk Anda mulai membuat apa pun yang Anda buat. Tapi itu bukan cara yang baik untuk merancang program.
djsmiley2kStaysInside

Jawaban:

7

Anda dapat menggunakan xargsutilitas untuk ini. Ia dapat menjalankan perintah untuk setiap baris di stdin, jadi kita hanya perlu memastikan bahwa xargsmendapat input satu baris pada stdin pada saat itu harus memulai perintah, yang dapat diselesaikan dengan grep:

proc1 | grep --max-count=1 "${targetString}" | xargs --max-lines=1 --no-run-if-empty --replace -- proc2

Argumen --max-count=1, --max-lines=1dan --no-run-if-emptymemastikan bahwa proc2dimulai tepat sekali jika dan kapan proc1keluaran ${targetString}untuk pertama kalinya, dan tidak pernah jika proc1tidak pernah keluaran ${targetString}. The --replaceMenghindari yang xargsmenambahkan garis input ke baris perintah.

Saya menggunakan baris perintah berikut untuk mengujinya:

(echo Start >&2; sleep 3 ; echo Trigger; sleep 3; echo End >&2) | grep --max-count=1 Trigger | xargs --max-lines=1 --no-run-if-empty --replace -- echo "Triggered"
Philipp Wendler
sumber
1
+1 Ini adalah jawaban yang sangat kreatif. Akan jauh lebih rumit jika Anda membutuhkan sisa output dari proc1. Anda harus menggunakan hal-hal seperti tee dan deskriptor file tambahan atau pipa bernama.
Joe
7

Saya tidak yakin ada perintah / jawaban yang elegan untuk pertanyaan yang Anda ajukan (yaitu mencapai titik tertentu dalam pelaksanaannya) - tetapi ada alat / teknik yang dapat digunakan untuk menyusun solusi, mungkin melibatkan lebih dari 1 dari berikut ini, dan mungkin hal-hal lain yang belum saya ketahui:

  1. Proses latar belakang (&)
  2. Eksekusi bersyarat (&& dan ||)
  3. tidur
  4. tunggu (saya berharap ini akan sangat berguna - jika Anda meluncurkan lebih dari 1 pekerjaan di latar belakang, itu akan menunggu sampai semua pekerjaan selesai)
  5. Bernama pipa (yang dapat menyediakan mekanisme untuk berbicara di antara proses).
  6. tidak menunggu menunggu

Menulis dan memeriksa file kunci juga merupakan praktik umum (tip pro - jika Anda memiliki kontrol lingkungan, tulis ke ramdisk daripada / tmp - pada banyak distro ini / dev / shm).

davidgo
sumber
6

Ini hanya sebuah ide, tetapi proseskan dulu pipa keluarannya ke grep. Mintalah grep pipe hasilnya ke loop garis baca, dan bandingkan setiap baris dengan apa yang Anda cari. Setelah ditemukan, jalankan proc2.

#!/bin/bash
targetString="line you are looking for"
proc1 | grep "${targetString}" |
while read line
do
if [ "$line" = "${targetString}" ]; then
    proc2
fi
done

Jika "titik tertentu dalam pelaksanaannya" dapat ditentukan oleh stdout, lalu bagaimana dengan yang berikut ini?

proc1 | grep "stdout trigger string" && proc2

&&harus menyala ketika grepkembali 0, yang hanya dilakukannya ketika menemukan kecocokan.

Louis Waweru
sumber
1
grep akan terus berjalan sampai stdin ditutup. Itu tidak akan mengembalikan apa pun (0 atau sebaliknya) sampai saat itu.
Bob
@ Bob Oh, terima kasih ... Saya akan mencoba untuk mengulangi ide ini.
Louis Waweru
@ Bob Ini akan sangat berantakan dan terputus-putus, dan penyalahgunaan alat, tetapi Anda bisa menggunakan fail2ban untuk memonitor file log (yaitu pipa stdout ke file), dan kemudian memprogram aturan untuk mengeksekusi skrip kedua ketika baris itu ditemukan (tapi saya rekomendasikan memodifikasi file pemicu dan menggunakan inotify adalah solusi yang lebih elegan)
davidgo
1
Jika targetstring terjadi lebih dari satu kali dalam output proc1, proc2 akan dijalankan beberapa kali. Jika Anda melakukannya proc2 &dan kemudian break, itu tidak akan terjadi, tetapi itu akan menutup pipa dan membuat proc1 berakhir sebelum waktunya. Atau, Anda dapat mengatur bendera setelah proc2 dimulai dan menggunakannya untuk memastikan proc2 tidak berjalan lagi. Seperti dengan jawaban yang lain, sisa output proc1 dibuang, jadi jika Anda membutuhkannya, lebih banyak pekerjaan diperlukan.
Joe
1
@ Jo Good point. Pertanyaan asli sebenarnya hanya bertanya tentang apa perintah yang tersedia untuk bekerja dengan, jadi ini benar-benar hanya sebuah jawaban menunjukkan beberapa potensi perintah-perintah (terutama |dan grepdi sini).
Louis Waweru