Bagaimana saya bisa sepenuhnya mencatat semua tindakan skrip bash?

44

Saya ingin mengambil SEMUA data log, baik dengan pesan kesalahan, dari output skrip saya, dan mengarahkan semuanya ke file log.

Saya punya skrip seperti di bawah ini:

#!/bin/bash
(
echo " `date` : part 1 - start "
ssh -f admin@server.com 'bash /www/htdocs/server.com/scripts/part1.sh logout exit'
echo " `date` : sleep 120"
sleep 120
echo " `date` : part 2 - start"
ssh admin@server.com 'bash /www/htdocs/server.com/scripts/part2.sh logout exit'
echo " `date` : part 3 - start"
ssh admin@server.com 'bash /www/htdocs/server.com/scripts/part3.sh logout exit'
echo " `date` : END"
) | tee -a /home/scripts/cron/logs

Saya ingin melihat semua tindakan dalam file /home/scripts/cron/logs

Tapi saya hanya melihat ini yang saya berikan setelah perintah echo.

Bagaimana cara check in log apakah perintah SSH berhasil?

Saya perlu mengumpulkan semua data log. Saya memerlukan ini untuk memantau hasil setiap perintah dalam skrip saya, untuk lebih menganalisis apa yang terjadi ketika skrip gagal.

BlueMark
sumber
Anda juga dapat menggunakan "skrip" untuk melakukan ini. Lihat posting ini: [di sini] [1] [1]: stackoverflow.com/questions/5985060/…
xX0v0Xx
Anda harus berhati-hati dengan errexit - Saya perhatikan itu diabaikan atau kesalahan tidak keluar skrip misalnya. jika Anda memiliki sesuatu seperti ini di skrip: command || dosmthg ketika perintah gagal skrip tidak langsung keluar dengan set errexit tetapi jalankan dosmthg dan lanjutkan skrip

Jawaban:

67

Saya biasanya meletakkan sesuatu yang mirip dengan yang berikut di awal setiap skrip (terutama jika itu akan dijalankan sebagai daemon):

#!/bin/bash
exec 3>&1 4>&2
trap 'exec 2>&4 1>&3' 0 1 2 3
exec 1>log.out 2>&1
# Everything below will go to the file 'log.out':

Penjelasan:

  1. exec 3>&1 4>&2

    Menyimpan deskriptor file sehingga mereka dapat dikembalikan ke apa pun mereka sebelum redirection atau digunakan sendiri untuk output apa pun mereka sebelum redirect berikut.

  2. trap 'exec 2>&4 1>&3' 0 1 2 3

    Kembalikan deskriptor file untuk sinyal tertentu. Biasanya tidak diperlukan karena mereka harus dikembalikan ketika sub-shell keluar.

  3. exec 1>log.out 2>&1

    Redirect stdoutke file log.outlalu redirect stderrke stdout. Perhatikan bahwa urutannya penting ketika Anda ingin mereka membuka file yang sama. stdout harus dialihkan sebelum stderrdiarahkan ke stdout.

Sejak saat itu, untuk melihat output di konsol (mungkin), Anda dapat mengarahkan ke &3. Sebagai contoh,

echo "$(date) : part 1 - start" >&3

akan pergi ke mana stdoutpun diarahkan, mungkin konsol, sebelum mengeksekusi baris 3 di atas.

nicerobot
sumber
<< Lebih bagus, terima kasih! Saya menambahkan threelines (exec, trap, exec) di awal skrip dan saya bisa mendapatkan stdout dan stderr. Tapi Satu masalah: Saya telah melihat "File descriptor 3 (pipe: XXX) bocor di some_command" ... Tolong beri tahu saya bagaimana saya bisa menghindari kesalahan ini. Saya menggunakan sh sibuk berdasarkan papan kustom.
kumar
3
Kungfu hebat di sini !!! - Bahkan lebih baik adalah menggunakan trap 'exec 2>&4 1>&3' 0 1 2 3 RETURN. RETURN pseudo sigspec mengembalikan deskriptor file setiap kali fungsi shell atau skrip dieksekusi dengan. atau sumber bawaan selesai dieksekusi. Untuk ini (dan untuk alasan lain) dalam skrip saya, saya menambahkan sebagai 2 baris terakhir: return& exit 0- Hanya 2 sen saya, pujian untuk Anda @nicerobot!
DavAlPi
Ada sejumlah detail yang bagus tentang pendataan untuk skrip shell melalui varaibles global shell. Kami dapat meniru jenis logging yang sama dalam skrip shell: cubicrace.com/2016/03/efisien-logging-mechnism-in-shell.html Posting memiliki detail tentang memperkenalkan level log seperti INFO, DEBUG, ERROR. Menelusuri detail seperti entri skrip, keluar skrip, entri fungsi, keluar fungsi.
Piyush Chordia
Pencacahan trapsinyal terlihat sedikit aneh. Biasanya Anda akan ingin memasukkan 15juga.
tripleee
1
@PiyushChordia memperbaiki tautan: cubicrace.com/2016/03/efisien-logging-mechnism-in-shell.html
vigilancer
14

untuk mendapatkan keluaran ssh ke logfile Anda, Anda harus mengarahkan ulang stderrke stdout. Anda dapat melakukan ini dengan menambahkan 2>&1setelah skrip bash Anda.

seharusnya terlihat seperti ini:

#!/bin/bash
(
...
) 2>&1 | tee ...

ketika ini tidak menampilkan mesages dalam urutan yang benar, cobalah untuk menambahkan subkulit lain:

#!/bin/bash
((
...
) 2>&1) | tee ...
Kristen
sumber
1
Ini sangat bagus. Sebenarnya Anda dapat mengarahkan stdout dan stderr dengan:( ... ) |& tee output.log
Noam Manos
13

Ketika saya membaca pertanyaan Anda, Anda tidak ingin mencatat output, tetapi seluruh urutan perintah, dalam hal ini, jawaban lain tidak akan membantu Anda.

Aktifkan skrip shell dengan -x untuk menampilkan semuanya:

sh -x foo.sh

Log ke file yang Anda inginkan dengan:

sh -x foo.sh >> /home/scripts/cron/logs

Alex Holst
sumber
2
+1 untuk opsi -x
Coc
10

Di bash, Anda bisa meletakkan set -xdan akan mencetak setiap perintah yang dieksekusi (dan variabel bash) setelah itu. Anda dapat mematikannya dengan set +x.

Jika Anda ingin menjadi paranoid, Anda dapat memasukkan set -o errexitskrip Anda. Ini berarti skrip akan gagal dan berhenti jika satu perintah mengembalikan kode keluar bukan nol, yang merupakan cara standar unix untuk memberi sinyal bahwa ada yang tidak beres.

Jika Anda ingin mendapatkan log lebih bagus, Anda harus melihat pada tsdi moreutilspaket debian / ubuntu. Ini akan mengawali setiap baris dengan cap waktu dan mencetaknya. Jadi Anda bisa melihat ketika sesuatu terjadi.

Rory
sumber
1
"set -o errexit" harus sama dengan "set -e"
Ajith Antony
0

Mengikuti apa yang orang lain katakan, set manual adalah sumber yang bagus. Saya meletakkan:

#!/usr/bin/env bash
exec 1> command.log 2>&1
set -x

Di bagian atas skrip, saya ingin melanjutkan, atau set -exjika harus keluar karena kesalahan.

dragon951
sumber
Bagaimana ini akan membantu untuk ssh log dan keberhasilan pelaksanaan perintah?
asktyagi
Menguji dengan skrip boneka OP, ia merekam setiap perintah dan apa pun hasilnya: ssh timeout, domain salah, dll. Atau untuk alamat ssh yang valid, ia merekam perintah di shell jauh. Jika info lebih lanjut tentang ssh login diperlukan, mungkin ssh -vv?
dragon951