GNU/Linux >> Belajar Linux >  >> Linux

Cara menghentikan perintah tee Linux tanpa mematikan aplikasi yang diterimanya

Ketika tee berakhir, perintah yang memberinya makan akan terus berjalan, hingga mencoba menulis lebih banyak keluaran. Kemudian akan mendapatkan SIGPIPE (13 pada sebagian besar sistem) untuk mencoba menulis ke pipa tanpa pembaca.

Jika Anda memodifikasi skrip Anda untuk menjebak SIGPIPE dan mengambil beberapa tindakan yang sesuai (seperti, berhenti menulis keluaran), maka Anda seharusnya dapat melanjutkannya setelah tee diakhiri.

Lebih baik lagi, daripada membunuh tee sama sekali, gunakan logrotate dengan copytruncate pilihan untuk kemudahan.

Mengutip logrotate(8) :

copytruncate

Potong file log asli di tempat setelah membuat salinan, alih-alih memindahkan file log lama dan secara opsional membuat yang baru. Ini dapat digunakan ketika beberapa program tidak dapat diminta untuk menutup file lognya dan dengan demikian mungkin terus menulis (menambahkan) ke file log sebelumnya selamanya. Perhatikan bahwa ada waktu yang sangat singkat antara menyalin file dan memotongnya, sehingga beberapa data logging mungkin hilang. Saat opsi ini digunakan, opsi buat tidak akan berpengaruh, karena file log lama tetap di tempatnya.


Menjelaskan "Mengapa"

Singkatnya:Jika penulisan gagal tidak menyebabkan program keluar (secara default), kita akan mengalami kekacauan. Pertimbangkan find . | head -n 10 -- Anda tidak ingin find untuk terus berjalan, memindai sisa hard drive Anda, setelah head telah mengambil 10 baris yang diperlukan dan melanjutkan.

Melakukannya Lebih Baik:Putar Di Dalam Logger Anda

Pertimbangkan yang berikut ini, yang tidak menggunakan tee sama sekali, sebagai contoh demonstratif:

#!/usr/bin/env bash

file=${1:-debug.log}                     # filename as 1st argument
max_size=${2:-100000}                    # max size as 2nd argument
size=$(stat --format=%s -- "$file") || exit  # Use GNU stat to retrieve size
exec >>"$file"                           # Open file for append

while IFS= read -r line; do              # read a line from stdin
  size=$(( size + ${#line} + 1 ))        # add line's length + 1 to our counter
  if (( size > max_size )); then         # and if it exceeds our maximum...
    mv -- "$file" "$file.old"            # ...rename the file away...
    exec >"$file"                        # ...and reopen a new file as stdout
    size=0                               # ...resetting our size counter
  fi
  printf '%s\n' "$line"                  # regardless, append to our current stdout
done

Jika dijalankan sebagai:

/mnt/apps/start.sh 2>&1 | above-script /tmp/nginx/debug_log

... ini akan dimulai dengan menambahkan /tmp/nginx/debug_log , mengganti nama file menjadi /tmp/nginx/debug_log.old ketika lebih dari 100KB konten hadir. Karena logger itu sendiri yang melakukan rotasi, tidak ada pipa yang rusak, tidak ada kesalahan, dan tidak ada jendela kehilangan data saat rotasi berlangsung -- setiap baris akan ditulis ke satu file atau lainnya.

Tentu saja, menerapkan ini di bash asli tidak efisien, tetapi di atas adalah contoh ilustratif. Ada banyak program yang tersedia yang akan mengimplementasikan logika di atas untuk Anda. Pertimbangkan:

  • svlogd , pencatat layanan dari rangkaian Runit.
  • s6-log , alternatif yang dipelihara secara aktif dari skanet suite.
  • multilog dari DJB Daemontools, nenek moyang keluarga alat pengawasan dan pemantauan proses ini.

Linux
  1. Cara Menghapus File dan Direktori di Linux dari Command Line

  2. Cara Memisahkan Dan Menggabungkan File Dari Baris Perintah Di Linux

  3. Perintah SCP Linux – Cara Transfer File SSH dari Jarak Jauh ke Lokal

  1. Perintah File Linux:Cara Menentukan Jenis File di Linux

  2. Cara Menyimpan Output Perintah ke File di Linux

  3. Bagaimana cara membuat file di Linux dari jendela terminal?

  1. Cara Menghapus (Menghapus) File atau Direktori di Linux

  2. Cara Mengekstrak atau Mengekstrak File tar.gz dari Baris Perintah Linux

  3. Cara Menggunakan Perintah md5sum di Linux