Dalam bash, dapatkah saya mengatur agar fungsi dijalankan sebelum menjalankan perintah?
Ada $PROMPT_COMMAND
, yang dieksekusi sebelum menampilkan prompt, yaitu, hanya setelah menjalankan perintah.
Bash $PROMPT_COMMAND
adalah analog dengan precmd
fungsi zsh ; jadi apa yang saya cari adalah bash setara dengan zsh preexec
.
Contoh aplikasi: atur judul terminal Anda ke perintah yang dijalankan; secara otomatis ditambahkan time
sebelum setiap perintah.
command-line
bash
hook
Gilles
sumber
sumber
PS0
variabel yang berfungsi sepertiPS1
tetapi digunakan setelah membaca perintah tetapi sebelum menjalankannya. Lihat gnu.org/software/bash/manual/bashref.html#Bash-VariablesJawaban:
Tidak asli, tetapi bisa diretas menggunakan
DEBUG
perangkap. Kode ini set uppreexec
danprecmd
fungsi mirip dengan zsh. Baris perintah diteruskan sebagai argumen tunggal kepreexec
.Berikut adalah versi kode yang disederhanakan untuk mengatur
precmd
fungsi yang dieksekusi sebelum menjalankan setiap perintah.Trik ini disebabkan oleh Glyph Lefkowitz ; terima kasih kepada bcat untuk menemukan penulis asli.
Sunting. Versi terbaru dari peretasan Glyph dapat ditemukan di sini: https://github.com/rcaloras/bash-preexec
sumber
"$BASH_COMMAND" = "$PROMPT_COMMAND"
perbandingan tidak bekerja untuk saya i.imgur.com/blneCdQ.pngtime for i in {1..10}; do true; done
membutuhkan waktu 0,040 detik secara normal dan 1,400 hingga 1,600 detik setelah mengaktifkan perangkap DEBUG. Ini menyebabkan perintah trap dieksekusi dua kali per loop - dan pada Cygwin forking yang diperlukan untuk mengeksekusi sed sangat lambat sekitar 0,030 detik untuk forking saja (perbedaan kecepatan antaraecho
builtin dan/bin/echo
). Sesuatu yang perlu diingat mungkin.PROMPT_COMMAND
variabel (misalnya dibatasi oleh;
), Anda mungkin perlu menggunakan pencocokan pola di baris kedua daripreexec_invoke_exec
fungsi, seperti ini:[[ "$PROMPT_COMMAND" =~ "$BASH_COMMAND" ]]
. Ini karenaBASH_COMMAND
mewakili masing-masing perintah secara terpisah.Anda dapat menggunakan
trap
perintah (darihelp trap
):Misalnya, untuk mengubah judul terminal secara dinamis, Anda dapat menggunakan:
Dari sumber ini .
sumber
help trap
mengatakan "Jika SIGNAL_SPEC adalah DEBUG, ARG dieksekusi setelah setiap perintah sederhana" [penekanan milikku].trap '[ -n "$COMP_LINE" ] && [ "$BASH_COMMAND" != "$PROMPT_COMMAND" ] && date "+%X";echo -e "\e]0;$BASH_COMMAND\007"' DEBUG
. Ini menempatkan perintah ke dalam judul dan juga mencetak waktu saat ini tepat sebelum setiap perintah, tetapi tidak melakukannya saat mengeksekusi$PROMPT_COMMAND
.[ -z "$COMP_LINE" ]
.Ini bukan fungsi shell yang dieksekusi, tapi saya berkontribusi
$PS0
string prompt yang ditampilkan sebelum setiap perintah dijalankan. Detail di sini: http://stromberg.dnsalias.org/~strombrg/PS0-prompt/$PS0
disertakan dalambash
4.4, meskipun akan memakan waktu cukup lama bagi sebagian besar Linux untuk memasukkan 4.4 - Anda dapat membangun 4.4 sendiri jika Anda mau; dalam hal ini, Anda mungkin harus meletakkannya di bawah/usr/local
, tambahkan ke/etc/shells
danchsh
ke sana. Kemudian logout dan kembali, mungkinssh
ke diri sendiri @ localhost atausu
ke diri sendiri terlebih dahulu sebagai ujian.sumber
Saya baru-baru ini harus menyelesaikan masalah yang tepat ini untuk proyek sampingan saya. Saya membuat solusi yang cukup kuat dan tangguh yang mengemulasi fungsionalitas preexec dan precmd zsh untuk bash.
https://github.com/rcaloras/bash-preexec
Ini awalnya didasarkan pada solusi Glyph Lefkowitz, tetapi saya telah memperbaikinya dan membawanya terkini. Senang membantu atau menambahkan fitur jika diperlukan.
sumber
Terima kasih atas petunjuknya! Saya akhirnya menggunakan ini:
Nikmati!
sumber
Saya menulis metode untuk mencatat semua perintah / built 'bash' ke dalam file teks atau server 'syslog' tanpa menggunakan patch atau alat yang dapat dieksekusi khusus.
Sangat mudah untuk digunakan, karena ini adalah shellscript sederhana yang perlu dipanggil sekali pada inisialisasi 'bash'.
Lihat metodenya di sini .
sumber