Apakah mungkin untuk mengalihkan semua output skrip Bourne shell ke suatu tempat, tetapi dengan perintah shell di dalam skrip itu sendiri?
Mengarahkan output dari satu perintah itu mudah, tetapi saya ingin sesuatu yang lebih seperti ini:
#!/bin/sh
if [ ! -t 0 ]; then
# redirect all of my output to a file here
fi
# rest of script...
Artinya: jika skrip dijalankan non-interaktif (misalnya, cron), simpan output dari segalanya ke file. Jika dijalankan secara interaktif dari shell, biarkan output pergi ke stdout seperti biasa.
Saya ingin melakukan ini untuk skrip yang biasanya dijalankan oleh utilitas periodik FreeBSD. Itu adalah bagian dari kegiatan harian, yang biasanya tidak saya perhatikan setiap hari melalui email, jadi saya tidak mengirimkannya. Namun, jika sesuatu di dalam skrip yang satu ini gagal, itu penting bagi saya dan saya ingin dapat menangkap dan mengirim email output dari bagian pekerjaan harian ini.
Pembaruan: Jawaban Joshua tepat, tetapi saya juga ingin menyimpan dan memulihkan stdout dan stderr di seluruh skrip, yang dilakukan seperti ini:
# save stdout and stderr to file descriptors 3 and 4, then redirect them to "foo"
exec 3>&1 4>&2 >foo 2>&1
# ...
# restore stdout and stderr
exec 1>&3 2>&4
exec 1>&3 2>&4 3>&- 4>&-
Jawaban:
Mengatasi pertanyaan saat diperbarui.
Kawat gigi '{...}' menyediakan unit pengalihan I / O. Kawat gigi harus muncul di mana perintah dapat muncul - secara sederhana, pada awal baris atau setelah titik koma. ( Ya, itu bisa dibuat lebih tepat; jika Anda ingin berdalih, beri tahu saya. )
Anda benar bahwa Anda dapat mempertahankan stdout asli dan stderr dengan pengalihan yang Anda tunjukkan, tetapi biasanya lebih mudah bagi orang-orang yang harus mempertahankan skrip nanti untuk memahami apa yang terjadi jika Anda lingkup kode diarahkan seperti yang ditunjukkan di atas.
Bagian yang relevan dari manual Bash yang Pengelompokan Perintah dan I / O Redirection . Bagian yang relevan dari spesifikasi shell POSIX adalah Compound Commands dan I / O Redirection . Bash memiliki beberapa notasi tambahan, tetapi sebaliknya mirip dengan spesifikasi shell POSIX.
sumber
>>
. Beberapa orang punya kebiasaan>
. Menambahkan selalu lebih aman dan lebih direkomendasikan daripada menghabiskan waktu. Seseorang menulis aplikasi yang menggunakan perintah salin standar untuk mengekspor beberapa data ke tujuan yang sama.Biasanya kami akan menempatkan salah satunya di atau dekat bagian atas skrip. Skrip yang menguraikan baris perintah mereka akan melakukan pengalihan setelah penguraian.
Kirim stdout ke file
dengan stderr
tambahkan stdout dan stderr ke file
Seperti yang Jonathan Leffler katakan dalam komentarnya :
exec
memiliki dua pekerjaan terpisah. Yang pertama adalah mengganti shell (skrip) yang saat ini dieksekusi dengan program baru. Yang lainnya adalah mengubah pengalihan I / O di shell saat ini. Ini dibedakan dengan tidak memiliki argumenexec
.sumber
exec
memiliki dua pekerjaan terpisah. Salah satunya adalah mengganti skrip saat ini dengan perintah lain, menggunakan proses yang sama - Anda menentukan perintah lain sebagai argumen untukexec
(dan Anda dapat men-tweak pengalihan I / O saat Anda melakukannya). Pekerjaan lainnya adalah mengubah pengalihan I / O dalam skrip shell saat ini tanpa menggantinya. Notasi ini dibedakan dengan tidak memiliki perintah sebagai argumenexec
. Notasi dalam jawaban ini adalah varian "I / O only" - hanya mengubah pengalihan dan tidak menggantikan skrip yang sedang berjalan. (set
Perintahnya juga multi-guna.)exec > >(tee -a "logs/logdata.log") 2>&1
mencetak log di layar dan juga menuliskannya ke dalam fileAnda dapat menjadikan seluruh skrip sebagai fungsi seperti ini:
maka pada akhir skrip miliki ini:
Atau, Anda dapat mencatat semuanya ke dalam logfile setiap kali dijalankan dan masih menampilkannya ke stdout dengan hanya melakukan:
sumber
Untuk menyimpan stdout dan stderr asli, Anda dapat menggunakan:
Misalnya, kode berikut akan mencetak "walla1" dan "walla2" ke file log (
a.txt
), "walla3" ke stdout, "walla4" ke stderr.sumber
exec 5>&1
danexec 6>&2
, menggunakan notasi redirection output daripada notasi redirection input untuk output. Anda lolos begitu saja karena ketika skrip dijalankan dari terminal, input standar juga dapat ditulis dan baik output standar dan kesalahan standar dapat dibaca berdasarkan (atau apakah itu 'wakil'?) Dari kekhasan sejarah: terminal dibuka untuk membaca dan menulis dan deskripsi file terbuka yang sama digunakan untuk ketiga deskriptor file I / O standar.sumber