Perilaku bash history yang aneh ketika menjalankan banyak sesi


15

Bagaimana sejarah baris perintah disimpan ketika saya menggunakan banyak terminal windows? Saya tahu ini disimpan .bash_historytetapi saya tidak bisa melihat logika tentang sejarah apa yang digunakan jika saya membuka jendela baru. Hampir terasa tidak pasti dalam arti bahwa saya tidak pernah tahu perintah apa yang akan saya lihat jika saya mencoba menggunakan panah di jendela baru.

Adakah yang bisa menjelaskan hal ini?

Apakah ada cara untuk mengontrol sejarah sedemikian rupa sehingga saya dapat menggunakan kembali sejarah dari jendela tertentu?

Jawaban:


14

Untuk memahami perilaku riwayat bash, Anda harus mengetahui hal berikut:

  1. Ada riwayat di file riwayat.
  2. Ada sejarah dalam memori proses bash.
  3. Riwayat di memori satu proses bash tidak disinkronkan dengan riwayat di memori proses bash lainnya.
  4. Riwayat dalam memori proses bash tidak disinkronkan dengan riwayat dalam file, kecuali diminta secara eksplisit ke atau selama beberapa peristiwa tertentu (lihat di bawah).

Menggunakan pengaturan default, siklus hidup dari sesi bash berkaitan dengan sejarah adalah sebagai berikut:

  1. Selama startup bash akan membaca file histori. Konten file histori sekarang ada di memori proses bash.
  2. Selama penggunaan normal hanya riwayat dalam memori yang dimanipulasi.
  3. Selama pematian histori dalam memori ditulis ke file histori, menimpa konten sebelumnya dari arsip histori.

Perilaku yang tampaknya tidak deterministik yang telah Anda amati sebagian besar karena isi dari file histori selalu sejarah dari sesi bash terakhir yang ditutup, dan bash hanya membaca file histori selama startup.

Baca manual bash untuk penjelasan lebih rinci tentang proses startup dan shutdown.

Perhatikan bahwa dengan pengaturan default yang saya maksud adalah pengaturan default dari bash. Distribusi Anda mungkin telah menyediakan .bashrc(atau /etc/bash.bashrc) yang mengubah perilaku ini.

Dengan mengaktifkan opsi shell, histappendAnda dapat memberi tahu bash untuk menambahkan alih-alih menimpa file histori. Anda dapat mengaktifkan histappendmenggunakan perintah shopt -s histappend. Agar opsi ini selalu diaktifkan, Anda harus meletakkan perintah di .bashrc(atau file inisialisasi lainnya). Baca lebih lanjut tentang shoptperintah di manual bash

Perhatikan bahwa mengaktifkan histappendtidak akan banyak mengurangi perilaku yang tampaknya tidak deterministik. Ini karena setiap sesi bash masih memiliki riwayatnya sendiri di memori. Dimungkinkan untuk memiliki sebagian besar riwayat pesta yang disinkronkan. Ada panduan bagaimana agar setiap proses bash memiliki sebagian besar riwayat yang disinkronkan di utas pada stack overflow .

menggunakan perintah builtin historyAnda dapat secara eksplisit memberitahu bash untuk membaca histori dari file ke memori, atau menulis dari memori ke file. Misalnya: history -rakan membaca konten file dan menambahkannya ke riwayat di memori. history -wakan menulis riwayat saat ini dari memori ke file, menimpa konten sebelumnya. Ini pada dasarnya apa yang terjadi selama shutdown. Baca lebih lanjut tentang historyperintah di manual bash

Untuk kelengkapan di sini adalah daftar variabel internal yang mengubah perilaku riwayat:

  • HISTFILE: file untuk membaca dan menulis sejarah.
  • HISTFILESIZE: jumlah baris maksimum untuk file histori.
  • HISTSIZE: jumlah baris maksimum untuk riwayat dalam memori.
  • HISTCONTROL, HISTIGNORE, HISTTIMEFORMAT: Tidak relevan untuk diskusi ini. Baca manual bash untuk detailnya.

Penjelasan yang bagus. Anda menyebutkan shutdown, tetapi bagaimana dengan membunuh sesi terminal? Sesi dapat dibunuh melalui logout atau melalui UI atau melalui beberapa cara lain seperti drop in koneksi jaringan. Jika seluruh file riwayat diganti dan Anda memiliki beberapa sesi, apakah Anda mengatakan bahwa riwayat dari yang terakhir ditutup akan digunakan dalam file riwayat? Itu bisa menjelaskan perilaku non deterministik.
Alex Gitelman

titik siklus hidup (3) tidak benar. Sepertinya hanya sesi bash pertama yang akan menulis ke file histori. Tes: Buka 2 sesi dalam urutan- a, b. Lakukan 'echo hello' di b . Kemudian keluar di b . Kemudian buka sesi baru c . Sesi ini tidak akan memiliki gema halo dalam riwayatnya.
user606723

@AlexGitelman: jika proses bash terbunuh maka itu tidak akan memiliki kesempatan untuk menimpa file histori. dan ya, riwayat dari sesi tertutup terakhir adalah yang akan ada di arsip riwayat.
lesmana

@ user606723: poin 3 benar. baca manual bash. bereksperimen lagi menggunakan .bashrcfile minimal . perhatikan bahwa distribusi Anda mungkin telah mengubah beberapa pengaturan di /etc/bash.bashrc. periksa secara spesifik untuk opsi shell histappend.
lesmana


0

AFAIK, perintah bash disimpan setelah sesi SSH dihentikan. Jadi, perintah tidak disimpan ketika sesi berakhir secara tidak normal (misalnya, karena kegagalan jaringan). Saya berbicara di sini tentang sesi SSH. Terminal lokal dapat menggunakan pendekatan serupa.

Saat membuka beberapa sesi secara bersamaan, perintah yang diketik pada satu sesi tidak terlihat di sesi lainnya saat keduanya aktif. Namun, Anda akan melihat perintah-perintah ini ketika Anda mengakhiri sesi Anda membukanya kembali.


Ini bukan perilaku yang saya alami. Saya dapat mengkonfirmasi ini dengan melakukan tes cepat di mana saya membuka sesi ssh, melakukan perintah, dan melakukan keluar dengan anggun. Dalam hal ini, saya memiliki sesi ssh yang sebelumnya aktif. Dalam sesi bash yang sudah ada sebelumnya, saya memeriksa .bash_history dan menemukan tidak ada yang direkam. Saya menemukan kemungkinan bahwa sesi bash pertama berjalan adalah satu-satunya yang akhirnya merekam ke .bash_history.
user606723

Mengakhiri sesi Anda tidak akan memengaruhi sesi yang sedang berjalan, tetapi akan memengaruhi sesi baru!
Khaled

Bagaimana jika bukan SSH tetapi jendela terminal Gnome yang saya tutup melalui UI?
Alex Gitelman

Itu perlu diverifikasi. Saat ini, saya tidak memiliki akses ke terminal Gnome!
Khaled

@ Khaled, Mengujinya, tidak memengaruhi sesi baru. (Saya telah memeriksa .bash_history sebelum apa pun, di mana bash mendapatkan histori perintah untuk sesi baru, saya sangat tahu itu tidak akan berhasil; t, tetapi saya tetap mengutak-atik Anda.)
user606723
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.