Saya tahu pertanyaan ini tidak jelas, karena ditanyakan di sini terus perbarui (dan digandakan di sini).
Apa yang saya coba capai sedikit berbeda. Saya tidak suka ide saya menulis ulang file setiap ls
Saya mengetik (history -a; history -c; history -r
).
Saya ingin memperbarui file saat keluar. Itu mudah (sebenarnya, default), tetapi Anda perlu menambahkan alih-alih menulis ulang:
shopt -s histappend
Sekarang, ketika terminal ditutup, saya ingin membuat semua terminal lain yang tetap terbuka mengetahui pembaruan.
Saya lebih suka melakukan ini tanpa memeriksa melalui $PS1
pada setiap command
yang saya ketik. Saya pikir akan lebih baik untuk menangkap semacam sinyal. Bagaimana Anda melakukannya? Jika tidak memungkinkan, mungkin cronjob
sederhana ?
Bagaimana kita bisa memecahkan teka-teki ini?
Jawaban yang Diterima:
Sinyal kreatif dan melibatkan, katamu? Oke:
trap on_exit EXIT
trap on_usr1 USR1
on_exit() {
history -a
trap '' USR1
killall -u "$USER" -USR1 bash
}
on_usr1() {
history -n
}
Buka itu di .bashrc
dan pergi. Ini menggunakan sinyal untuk memberi tahu setiap bash
proses untuk memeriksa entri riwayat baru ketika yang lain keluar. Ini cukup mengerikan, tetapi ini benar-benar berhasil.
Bagaimana cara kerjanya?
trap
menetapkan penangan sinyal baik untuk sinyal sistem atau salah satu acara internal Bash. EXIT
event adalah penghentian terkontrol dari shell, sedangkan USR1
adalah SIGUSR1
, sinyal tidak berarti yang kami ambil.
Setiap kali shell keluar, kita:
- Tambahkan semua riwayat ke file secara eksplisit.
- Nonaktifkan
SIGUSR1
handler dan membuat shell ini mengabaikan sinyal. - Kirim sinyal ke semua
bash
yang sedang berjalan proses dari pengguna yang sama.
Ketika SIGUSR1
tiba, kami:
- Muat semua entri baru dari file riwayat ke dalam daftar riwayat dalam memori shell.
Karena cara Bash menangani sinyal, Anda tidak akan benar-benar mendapatkan data riwayat baru sampai Anda menekan Enter lain kali, jadi ini tidak lebih baik daripada meletakkan history -n
ke dalam PROMPT_COMMAND
. Itu menghemat membaca file terus-menerus ketika tidak ada yang terjadi, dan tidak ada penulisan sama sekali sampai shell keluar.
Namun, masih ada beberapa masalah di sini. Yang pertama adalah respon default untuk SIGUSR1
adalah untuk mengakhiri shell. bash
lainnya proses (menjalankan skrip shell, misalnya) akan dimatikan. .bashrc
tidak dimuat oleh shell non-interaktif. Sebagai gantinya, sebuah file bernama BASH_ENV
dimuat:Anda dapat mengatur variabel itu di lingkungan Anda secara global untuk menunjuk ke file dengan:
trap '' USR1
di dalamnya untuk mengabaikan sinyal di dalamnya (yang menyelesaikan masalah).
Terkait:Perintah terminal untuk mengetahui apakah server itu virtual atau fisik?Akhirnya, meskipun ini melakukan apa yang Anda minta, pemesanan yang Anda dapatkan akan sedikit tidak biasa. Secara khusus, bit riwayat akan diulang dalam urutan yang berbeda saat dimuat dan disimpan secara terpisah. Itu pada dasarnya melekat pada apa yang Anda minta, tetapi perlu diketahui bahwa riwayat panah ke atas menjadi jauh kurang berguna pada saat ini. Pergantian riwayat dan sejenisnya akan dibagikan dan berfungsi dengan baik.