GNU/Linux >> Belajar Linux >  >> Linux

Riwayat BASH terpotong menjadi 500 baris pada setiap login

Masalahnya sebenarnya bermuara pada perilaku yang berbeda dari shell login dan non-login. Saya telah menetapkan variabel yang mengontrol riwayat di ~/.bahsrc saya . File ini tidak dibaca ketika seseorang memulai shell login, itu hanya dibaca oleh shell non-login yang interaktif (dari man bash ):

Saat bash dipanggil sebagai shell login interaktif, atau sebagai shell anon-interaktif dengan --login pilihan, pertama membaca dan mengeksekusi perintah dari file /etc/profile , jika file itu ada. Setelah membaca file itu, ia mencari ~/.bash_profile,~/.bash_login , dan ~/.profile , dalam urutan itu, dan membaca dan menjalankan perintah dari yang pertama yang ada dan dapat dibaca. --noprofile opsi dapat digunakan saat shell dimulai untuk menghambat perilaku ini.

[. . . ]

Ketika shell interaktif yang bukan shell login dimulai, bash membaca dan mengeksekusi perintah dari ~/.bashrc, jika file itu ada. Ini dapat dihambat dengan menggunakan opsi --norc. Opsi --rcfile file akan memaksa bash untuk membaca dan menjalankan perintah dari file alih-alih ~/.bashrc.

Oleh karena itu, setiap kali saya login, atau membuka tty, atau menggunakan ssh, .history file terpotong karena saya belum menyetelnya ke ukuran yang tepat di ~/.profile demikian juga. Saya akhirnya menyadari hal ini dan cukup mengatur variabel di ~/.profile tempatnya, bukan ~/.bashrc

Jadi, alasan ~/.history saya terpotong adalah karena saya hanya menyetel variabel HISTORY dalam file yang dibaca oleh shell non-login yang interaktif dan oleh karena itu setiap kali saya menjalankan jenis shell yang berbeda, variabel akan diabaikan dan file akan dipotong sesuai dengan itu.


Saran saya adalah menggunakan file lain sebagai HISTFILE , bukan ~/.bash_history default .

Meskipun saya tidak memiliki penjelasan analitik, saya akan mencoba menguraikan apa yang mengarahkan saya ke saran ini:Jika Anda menggunakan bash sebagai shell (login) default Anda dan juga menggunakan X (yang keduanya sangat mungkin) Anda menjalankan bash contoh tepat setelah login (grafis):

systemd
 ...
  |-login
  |   `-bash      <<====
  |       `-slim
  |           |-X -nolisten tcp vt07 -auth /var/run/slim.auth
  |           |  `-{X}
  |           `-fluxbox
  |               `-xterm -bg black -fg white
  |                   `-bash
 ...

Saya pikir instance ini adalah shell login, jadi tidak membaca ~/.bashrc Anda dan karenanya tidak akan tahu apa-apa tentang histappend opsi:

man bash(1) :Saat shell interaktif yang bukan login shell dimulai, bash membaca dan mengeksekusi perintah dari /etc/bash.bashrc dan ~/.bashrc, jika file-file ini ada. (...)

Selama "induk shell" ini berjalan, semuanya baik-baik saja, tetapi setelah penghentiannya (yaitu penghentian sistem) itu akan menggantikan ~/.bash_history (karena itu adalah nilai default) dan mengacaukan riwayat Anda atau memotongnya di sistem mulai (sekali lagi default) 500 baris. (Atau mungkin keduanya...)

Saya juga terkejut, bahwa tidak cukup untuk menyertakan konfigurasi riwayat di ~/.bashrc , karena ini seharusnya bukan penyiapan yang tidak biasa. Saya tidak punya penjelasan untuk itu.

Mengenai masalah Anda, bahwa "Login shell masih menampilkan perilaku yang sama", Anda dapat mencoba memasukkan konfigurasi riwayat juga di ~/.bash_profile :

man bash(1) :Ketika bash dipanggil sebagai shell login interaktif, atau sebagai shell non-interaktif dengan opsi --login, pertama-tama bash membaca dan menjalankan perintah dari file /etc/profile, jika file itu ada. Setelah membaca file itu, ia mencari ~/.bash_profile, (...)

Sayangnya saya tidak dapat memposting penjelasan yang lebih masuk akal dengan detail dari bash saya sendiri config, karena saya adalah zsh pria...


Karena semua pengaturan Anda sesuai dengan halaman manual, dan karena file riwayat tidak dibatasi oleh ukuran (byte), satu-satunya penjelasan yang dapat saya pikirkan. Ini ada hubungannya dengan bagaimana cangkang mati.

Menurut referensi online, keluar dengan anggun (riwayat disimpan) hanya terjadi ketika shell menerima SIGHUP. Saya tidak dapat benar-benar menjelaskan bagaimana sistem Anda menyebarkan sinyal saat di-boot ulang, tetapi saya menduga shell Anda berhenti dengan SIGKILL atau SIGPWR.

Bisa jadi karena WM Anda berjalan secara tidak sinkron (tunggu) dan emulator terminal muncul dari WM tempat bash mendapatkan sinyal pemaksaan keluar selain SIGHUP. Bisa juga OS terlalu cepat mengirim "pembunuhan terakhir" ke semua proses sebelum SIGHUP awal yang anggun berhasil masuk ke shell melalui X -> WM -> xterm, mungkin karena X atau WM membutuhkan waktu lebih lama untuk keluar daripada dibutuhkan agar OS siap untuk turun.

Saya berada di perairan yang dalam dengan hal ini, tetapi saya pikir sesuatu di sepanjang garis itu menyebabkan perilaku yang tidak menentu. Saya pernah mengalami masalah ini sebelumnya, dan solusi yang paling tepat adalah exit di bash tempat Anda ingin menyimpan sejarah.

Saya perhatikan history -a dalam pertanyaan Anda, dan saya tidak dapat memikirkan mengapa itu tidak cukup untuk melestarikan sejarah.

Anda dapat memecahkan masalah dengan mencari tahu apa yang benar-benar membunuh bash Anda dan beralih ke mencari tahu dari mana asal sinyal dan memperbaiki masalah di sana, atau cukup bersihkan riwayat ketika Anda tahu sinyal mana yang terakhir (dengan asumsi disk masih online saat itu ):

trap "echo got 1  >/tmp/sig1;  exit" SIGHUP
trap "echo got 2  >/tmp/sig2;  exit" SIGINT
trap "echo got 15 >/tmp/sig15; exit" SIGTERM
 .. and so on...

Tangkapan layar yang disertakan mengilustrasikan apa yang saya bicarakan di paragraf kedua dan ketiga. Urutannya adalah saya shell in dari kiri , bunuh cangkang kiri dari kanan dan cat sejarahnya.

man bash

Saat startup, (...) File yang dinamai dengan nilai HISTFILE dipotong, jika perlu, berisi lebih dari jumlah baris yang ditentukan oleh nilai HISTFILESIZE (+ default 500).

Jika opsi shell histappend diaktifkan (+ default di sini), baris ditambahkan ke file riwayat, jika tidak, file riwayat akan ditimpa.

referensi online

3.7.6 Sinyal

Saat Bash bersifat interaktif, jika tidak ada jebakan, Bash akan mengabaikan SIGTERM (sehingga 'kill 0' tidak mematikan shell interaktif), dan SIGINT ditangkap dan ditangani (sehingga builtin wait dapat diinterupsi). Saat Bash menerima SIGINT, Bash keluar dari loop eksekusi apa pun. Dalam semua kasus, Bash mengabaikan SIGQUIT. Jika kontrol pekerjaan aktif (lihat Kontrol Pekerjaan), Bash mengabaikan SIGTTIN, SIGTTOU, dan SIGTSTP.

Perintah non-builtin yang dimulai oleh Bash mengatur penangan sinyal ke nilai yang diwarisi oleh shell dari induknya. Saat kontrol pekerjaan tidak berlaku, perintah asinkron mengabaikan SIGINT dan SIGQUIT selain penangan yang diwariskan ini. Perintah yang dijalankan sebagai hasil dari substitusi perintah mengabaikan sinyal kontrol pekerjaan yang dihasilkan keyboard SIGTTIN, SIGTTOU, dan SIGTSTP.

Shell keluar secara default setelah menerima SIGHUP. Sebelum keluar, shell interaktif mengirim ulang SIGHUP ke semua pekerjaan, berjalan atau berhenti. Pekerjaan yang dihentikan dikirim SIGCONT untuk memastikan bahwa mereka menerima SIGHUP. Untuk mencegah shell mengirim sinyal SIGHUP ke tugas tertentu, itu harus dihapus dari tabel pekerjaan dengan disown bawaan (lihat Bawaan Kontrol Pekerjaan) atau ditandai untuk tidak menerima SIGHUP menggunakan disown -h.

Jika opsi shell huponexit telah disetel dengan shopt (lihat The Shopt Builtin), Bash mengirimkan SIGHUP ke semua tugas saat shell login interaktif keluar.

Jika Bash sedang menunggu perintah selesai dan menerima sinyal yang jebakannya telah dipasang, jebakan tidak akan dieksekusi sampai perintah selesai. Ketika Bash sedang menunggu perintah asinkron melalui builtin tunggu, penerimaan sinyal yang jebakannya telah ditetapkan akan menyebabkan builtin tunggu segera kembali dengan status keluar lebih besar dari 128, segera setelah jebakan dijalankan.

tangkapan layar demonstratif


Linux
  1. CentOS / RHEL :Cara menonaktifkan riwayat shell BASH

  2. Setel ulang posisi pencarian riwayat bash

  3. Jalankan skrip bash setelah login

  1. Cara menggunakan perintah riwayat Bash

  2. Tetapkan Tanggal dan Waktu untuk Setiap Perintah yang Anda Jalankan di Bash History

  3. Bagaimana caranya:Riwayat Bash/Shell yang tidak terbatas?

  1. Fungsi Dalam Variabel Shell?

  2. Pembersihan Otomatis Sejarah Bash?

  3. Cara Memeriksa Riwayat Masuk Linux