Saya memiliki skrip bash dengan berbagai pernyataan if berdasarkan argumen baris perintah yang saya berikan ketika memanggilnya. Memiliki semacam keluaran untuk perintah apa yang sedang dijalankan sangat membantu untuk mengkonfirmasi aliran melalui semua pernyataan if, tetapi solusi saya saat ini memberi saya terlalu banyak informasi.
Menggunakan set -v
dalam skrip agak membantu untuk melihat perintah yang dicetak ke layar saat dijalankan di skrip, namun saya mendapatkan terlalu banyak perintah. Hampir seperti seluruh salinan naskah.
Saya ingin output yang menunjukkan perintah apa yang sedang dijalankan, tetapi saya tidak ingin melihat komentar, baris baru, ekspresi dalam pernyataan if, dll.
Apakah ada cara saya bisa melewatkan semua kemungkinan output yang dihasilkan oleh opsi -v melalui regex terlebih dahulu sebelum dicetak? Atau beberapa solusi lain untuk mendapatkan bash hanya dengan perintah output dari "tipe" tertentu (mis. Yang menggunakan executable dan bukan hanya bash pernyataan spesifik, komentar dll?)
[1] /programming/257616/sudo-changes-path-why sangat membantu dalam hal ini dan saya mendapat saran untuk set -v
penggunaannya.
Edit :
Skrip yang mirip (tetapi tidak identik) dengan skrip yang saya jalankan:
#!/bin/bash
#get verbose command output
set -v
env=$1
if [ "$env" == "dev" ]; then
python ascript.py
fi
if [ "$env" == "prod" ]; then
#launching in prod will most likely fail if not run as root. Warn user if not running as root.
if [ $EUID -ne 0 ]; then
echo "It doesn't look like you're running me as root. This probably won't work. Press any key to continue." > /dev/stderr
read input
fi
#"stop" any existing nginx processes
pkill -f nginx
nginx -c `pwd`/conf/artfndr_nginx.conf
fi
Saya hanya ingin 2 set jalur output dari skrip ini. Pertama:
python ascript.py
Kedua:
pkill -f nginx
nginx -c /some/current/directory/conf/artfndr_nginx.conf
sumber
set -v
output yang Anda inginkan dan mana yang tidak.Jawaban:
Ketika saya menulis skrip bash yang lebih kompleks, saya menggunakan sedikit fungsi untuk menjalankan perintah yang juga akan mencetak perintah yang dijalankan ke file log:
Kemudian, dalam skrip saya, saya menjalankan perintah seperti ini:
Jika Anda tidak ingin perintah dicetak, jalankan saja secara normal.
Anda dapat mengatur
$LOG
ke nama file atau hanya menghapusnya dan mencetak ke stdout atau stderr.sumber
v python ascript.py
tanpa harus menyertakan dalam kutipan dan kehilangan penyorotan kode vimeval ..... || ok=1
: akan ditetapkan ok ke "1" hanya ketika "eval ..." gagal ?? Mungkin maksudmu "&&"? Dan jika Anda maksudkan itu, tambahkan "ok = 0" sebelum baris eval, jadi "reset" setiap kali. Atau cukup ganti nama "ok" menjadi "error"? sepertinya itulah yang dimaksud di sini. Jadi pada akhirnya:eval "$@" 2>> "$LOG" && error=0 || error=1
ok
variabel yang akan menghentikan skrip jika ada perintah yang gagal. Karena itu tidak relevan di sini, saya menghapusnya tetapi lupa menghapus|| ok=1
. Terima kasih, perbaiki sekarang."
pernyataan eval yang mengelilinginya, karena perintah sudah dikelilingi oleh"
sGunakan sub-shell, yaitu:
Sebagai contoh:
cetakan
sumber
set -x; cmd; set +x
karena beberapa alasan. Pertama, itu tidak me-resetset -x
kalau-kalau sudah hidup sebelumnya. Kedua, penghentian skrip di dalamnya tidak menyebabkan jebakan dieksekusi dengan pengaturan verbose aktif.Saya telah melihat metode yang digunakan mirip dengan @ terdon. Ini adalah awal dari apa yang disebut oleh bahasa pemrograman tingkat tinggi logger, dan menawarkan pustaka yang ditiup penuh, seperti log4J (Java), log4Perl (Perl) dll.
Anda bisa mendapatkan sesuatu yang serupa menggunakan
set -x
di Bash seperti yang telah Anda sebutkan tetapi Anda dapat menggunakannya untuk mengaktifkan debugging hanya sebagian dari perintah dengan membungkus blok kode dengan mereka seperti itu.Contohnya
Berikut adalah pola satu garis yang dapat Anda gunakan.
Anda dapat membungkusnya seperti ini untuk beberapa perintah dalam skrip.
Log4Bash
Kebanyakan orang tidak menyadari tetapi Bash juga memiliki log4 * juga, Log4Bash . Jika Anda memiliki kebutuhan yang lebih sederhana, ini mungkin sepadan dengan waktu untuk mengaturnya.
Contohnya
Berikut adalah beberapa contoh penggunaan log4bash.
Log4sh
Jika Anda menginginkan apa yang akan saya klasifikasikan sebagai kekuatan penuh kerangka log4 * maka saya akan mencoba Log4sh .
kutipan
Log4sh mendukung beberapa shell, bukan hanya Bash.
Ini juga telah diuji pada beberapa OS, bukan hanya Linux.
Menggunakan kerangka kerja log4 * akan membutuhkan waktu untuk mempelajarinya, tetapi itu sangat berharga jika Anda memiliki lebih banyak kebutuhan dari pencatatan Anda. Log4sh menggunakan file konfigurasi tempat Anda dapat mendefinisikan appenders dan mengontrol format untuk output yang akan muncul.
Contoh
Sekarang ketika saya menjalankannya:
CATATAN: Di atas mengkonfigurasi appender sebagai bagian dari kode. Jika Anda suka ini dapat diekstraksi ke file sendiri,
log4sh.properties
dll.Konsultasikan dokumentasi yang sangat baik untuk Log4sh jika Anda memerlukan detail lebih lanjut
sumber
set
perintah yang saya perlu perkenalkan, bergantian di sekitar komentar dll, jadi hanya memiliki fungsi di bagian atas skrip saya, dengan panggilan fungsi karakter tunggal yang ditambahkan ke semua baris "penting" dalam skrip tampak lebih rapi bagi saya untuk saat ini. (karakter tunggal karena fungsinya memiliki nama karakter tunggal)echo
fungsi saya sendirimecho
,, dan kemudian beralih ke program yang disebut-v
verbose ketika saya ingin mematikan semuanya. Saya juga bisa mengendalikannya dengan saklar argumen ke-2 yang menentukan nama fungsi, jadi saya punya 2 sumbu untuk mengontrol pencatatan. Ini sering merupakan gateway untuk menginginkan log4bash.set -x
mencetak perintah saat dijalankan. Itu tidak mencetak komentar.set -x
praktis untuk debugging (tidak sepertiset -v
yang tidak terlalu berguna). Zsh memiliki output yang lebih baikset -x
daripada bash, misalnya menunjukkan fungsi yang saat ini sedang dieksekusi dan nomor baris sumber.Anda bisa
trap
DEBUG
dan kemudian menguji yangBASH_COMMAND
variabel . Tambahkan ini ke bagian atas skrip:Kode dapat dibaca; itu hanya menguji apakah argumen pertama dimulai dengan
python
ataupkill
, dan mencetaknya jika itu masalahnya. Dan trap menggunakanBASH_COMMAND
(yang berisi perintah yang akan dieksekusi) sebagai argumen pertama.Perhatikan bahwa saat
case
menggunakan gumpalan, Anda bisa dengan mudah melakukannya:Dan gunakan ekspresi reguler.
sumber
Ini adalah versi revisi dari fungsi rapi Steven Penny. Ini mencetak argumen dalam warna dan mengutipnya sesuai kebutuhan. Gunakan untuk memilih perintah yang ingin Anda lacak secara selektif. Karena kutipan adalah output, Anda dapat menyalin garis yang dicetak dan menempelnya ke terminal untuk segera dieksekusi kembali saat Anda sedang men-debug sebuah skrip. Baca komentar pertama untuk mengetahui apa yang saya ubah dan mengapa.
Contoh penggunaan dengan output:
# xc echo "a b" "c'd" "'" '"' "fg" '' " " "" \# this line prints in green
echo 'a b' c\'d \' '"' fg '' ' ' '' '#' this line prints in green
a b c'd ' " fg # this line prints in green
Baris kedua di atas mencetak dalam warna hijau dan dapat disalin-salin untuk mereproduksi baris ketiga.
Keterangan Lebih Lanjut
@ Steven-Penny xc asli itu cerdas dan dia layak mendapatkan semua pujian untuk itu Namun, saya melihat beberapa masalah, tetapi saya tidak dapat mengomentari posnya secara langsung karena saya tidak memiliki reputasi yang cukup. Jadi saya membuat edit yang disarankan untuk posnya tetapi pengulas menolak suntingan saya. Karena itu saya memilih untuk memposting komentar saya sebagai jawaban ini, meskipun saya lebih suka untuk dapat mengedit jawaban Steve Penny sendiri.
Apa yang saya ubah adalah jawaban Steven-Penny
Diperbaiki: mencetak string null - tidak dicetak. Tetap: mencetak string yang menyertakan
%
- mereka menyebabkan kesalahan sintaks awk. Digantifor (j in ...)
denganfor (j = 0, ...)
karena yang pertama tidak menjamin urutan array traversal (tergantung awk implementasi). Menambahkan 0 ke angka oktal untuk portabilitas.Memperbarui
Steven Penny sejak itu memperbaiki masalah-masalah itu dalam jawabannya, jadi komentar-komentar ini tetap hanya untuk catatan sejarah jawaban saya. Lihat bagian Komentar untuk perincian lebih lanjut.
sumber
Anda dapat menggunakan fungsi shell "sh_trace" dari perpustakaan stdlib POSIX untuk mencetak perintah dalam warna sebelum menjalankannya. Contoh:
Fungsi Awk yang mendasarinya:
sumber