Cara berbagi sejarah bashing di antara berbagai tab

19

Saya menggunakan jawabannya di /unix//a/1292/41729 untuk mengaktifkan riwayat bersama waktu nyata di antara terminal bash yang terpisah. Sebagaimana dijelaskan dalam jawaban di atas, ini dicapai dengan menambahkan:

# avoid duplicates..
export HISTCONTROL=ignoredups:erasedups  
# append history entries..
shopt -s histappend

# After each command, save and reload history
export PROMPT_COMMAND="history -a; history -c; history -r; $PROMPT_COMMAND"

Ini berfungsi dengan baik jika shell bash terpisah (misalnya membuka terminal bash yang berbeda menggunakan CTRL+ALT+T. Namun tidak berfungsi jika saya menggunakan tabs(dari terminal terbuka `CTRL + SHIFT + T) daripada jendela baru. Mengapa perbedaan perilaku ini? Bagaimana dapatkah saya membagikan sejarah bash juga di antara berbagai tab?

UPDATE: Saya melihat perilaku yang tidak biasa: jika saya mengetik CTRL+Cmaka perintah terakhir yang diketikkan di terminal lain (baik tab atau tidak) ditampilkan dengan benar. Ini seperti jika CTRL + C memaksa pembilasan sejarah sehingga kemudian dibagikan dengan benar.

Sebagai contoh output (T1 menunjukkan terminal 1 dan terminal 2 T2):

T1:
ls -lah <enter>
# the list of files and directory is shown

T2:
cd Documents <enter>

T1:
<up> (i.e. I press the up arrow)
ls -lah #i.e the last command in terminal 1 is shown rather than the last of terminal 2
^C (i.e. I press CTRL+C)
<up>
cd Documents #the last command issued in terminal 2 is correctly displayed

Semoga ini bisa memberikan petunjuk!

lucacerone
sumber
Anda menambahkan itu ke ~.bashrcfile Anda ? Sebagai tambahan, mengekspor variabel-variabel itu tidak ada gunanya; hanya membuang-buang ruang lingkungan.
geirha
@geirha ya saya telah menambahkan ke file .bashrc saya. Terima kasih atas komentarnya pada ekspor.
lucacerone

Jawaban:

2

Sepertinya Anda mencoba mengakses riwayat terminal lain sebelum sinkronisasi dilakukan. PROMPT_COMMANDdijalankan tepat sebelum prompt baru dicetak, yaitu, setelah Anda menjalankan perintah dan sebelum Anda mengetik perintah berikutnya. Jadi itu tidak akan terjadi segera di T1; Anda harus membuat prompt baru untuk ditampilkan.

Untuk menguji ini, coba varian ini pada langkah Anda (saya menambahkan ekstra <enter>di T1):

T1:
ls -lah <enter>
# the list of files and directory is shown

T2:
cd Documents <enter>

T1:
<enter>
<up> (i.e. I press the up arrow)

Dengan tambahan tekan enter ini, Anda mendapatkan prompt baru, yang menjalankan PROMPT_COMMANDdan menyinkronkan riwayat Anda, jadi saya berharap panah atas ini untuk mengambil cdalih - alih ls, seperti yang Anda inginkan. Sayangnya, saya tidak berpikir ada cara untuk membuat sinkronisasi terjadi secara instan di semua terminal tanpa menjalankan perintah seperti yang Anda inginkan; efektif ini akan memerlukan semua sesi login Anda untuk menyinkronkan daftar riwayat mereka terus menerus setiap saat, yang akan menjadi pemborosan besar dari CPU dan disk throughput.

Paul
sumber
Anda benar, menekan enter itu disinkronkan setelah. Bahkan jika ada pemborosan memori atau CPU bagaimana saya bisa memaksakan sinkronisasi? (Jika terlalu banyak saya selalu dapat menonaktifkannya, tetapi saya ingin mencobanya)
lucacerone
1

Saya mengajukan pertanyaan yang sama dan inilah jawaban yang saya dapatkan ....

HISTSIZE=9000
HISTFILESIZE=$HISTSIZE
HISTCONTROL=ignorespace:ignoredups

history() {
  _bash_history_sync
  builtin history "$@"
}

_bash_history_sync() {
  builtin history -a         #1
  HISTFILESIZE=$HISTSIZE     #2
  builtin history -c         #3
  builtin history -r         #4
}

PROMPT_COMMAND=_bash_history_sync
Scott Goodgame
sumber
Sumber: unix.stackexchange.com/a/48116/37944
Radu Rădeanu
dua klarfikasi sebelum saya coba: haruskah saya menghapus histeria - opsi lainnya? ini berjalan di. Bashrc benar?
lucacerone
sayangnya itu tidak berhasil ...
lucacerone
Setiap kali HISTFILESIZEdiubah secara otomatis mencoba untuk memotong file riwayat yang ada. Mengubah HISTSIZEmemiliki efek yang sama pada riwayat saat ini. Untuk referensi, lihat komentar di variables.cdalam bash src sebelum sv_histsize.
Brian Vandenberg
1

tambahkan baris itu ke .bashrcfile Anda

# avoid duplicates..
export HISTCONTROL=ignoredups:erasedups  
# append history entries..
shopt -s histappend

trap 'history -r' USR1 
export PROMPT_COMMAND="history -a ; history -c; ps a | awk '/ bash$/ {system (\"kill -USR1 \" \$1)}'; $PROMPT_COMMAND"

catatan:

Awalnya saya melakukan test bay saya mengirim sinyal USR1 ke bash dengan killall, kemudian saya berpikir untuk menggunakan nama shell unik, salinan bash bernama testshell, untuk menghindari membunuh cangkang saya sendiri yang bisa berjalan (proses cron misalnya) tetapi anehnya itu tidak kerja.

Killall itu tidak cukup selektif, saya menggantinya dengan skrip yang membunuh hanya proses bash ketat hingga tty ( ps alaporan hanya proses terkait dengan tty)

Jangan lupa untuk memulai kembali sesi Anda untuk mendapatkan PROMPT_COMMAND baru, ketika saya menguji saya melihat banyak dari tes saya sebelumnya ditumpuk di dalam PROMPT_COMMAND.

Emmanuel
sumber
Anda tidak memerlukan pengguna baru dan shell lainnya, Anda hanya dapat memberitahu killalluntuk mengirim sinyal hanya ke proses dari pengguna yang sama dengan -uargumen tambahan , e.g. -u $ (whoami) `.
Philipp Wendler
Saya pikir sintaks untuk csh salah ... @ Phippippendend dapatkah Anda menjelaskan sedikit?
lucacerone
Pertanyaannya adalah tentang bash, jadi saya menggunakan sintaks bash. Saya tidak tahu csh. Untuk bash, killall -q -USR1 -u $(whoami) bashmengirim sinyal USR1 ke semua proses bash dari pengguna saat ini.
Philipp Wendler
@Philipp ty btw Saya tidak menguji solusi shell khusus, itu untuk memperbaiki kasus di mana skrip bash cron akan berjalan.
Emmanuel
@LucaCerone Saya menulis ulang sepertinya berhasil
Emmanuel
0

Saya memiliki perilaku aneh yang sama di Yakuake ketika mencoba membuat bash prompt yang rumit yang akan menunjukkan jumlah login lain. Nomor tidak bertambah untuk tab. Solusi saya adalah memberi tahu Yakuake berlari bashlagi di setiap tab baru, pada dasarnya memulai bash in bash. Itu mulai bekerja dengan sempurna. Mungkin itu akan membantu Anda juga. Tebakan buta saya adalah bahwa GUI untuk konsol memuat bash mengkonfigurasi sendiri dan kemudian mengumpankannya ke instance bash. Mungkin itu adalah untuk bisa bermain-main dengan mereka.

Barafu Albino
sumber
Saya telah mencoba memuat bash di bash, tetapi tanpa hasil :(
lucacerone