BASH geçmişi her girişte 500 satıra kesildi


22

Bazı nedenlerden dolayı, sistemimi yeniden başlattıktan sonra BASH geçmişimi saklayamıyorum. İşte benim ilgili bölümler ~/.bashrc:

shopt -s histappend
PROMPT_COMMAND='history -a; updateWindowTitle'
export HISTCONTROL=ignoredups
export HISTSIZE=9999
export HISTFILESIZE=999999
export HISTFILE="$HOME/.bash_history"

Bunların hepsinin gerekli seçenekler olduğunu söyleyebildiğim kadarıyla ( geçmişte bunların hepsi olmadan tarihi birden çok yeniden başlatma arasında tutabildiğimi biliyorum ). Ancak, bu seçenekleri birkaç yeniden başlatmadan önce eklemiş olmama rağmen, bir yeniden başlatmadan sonra tarihimin çoğunu hala kaybediyorum. Boş değil, ancak yeniden başlatmadan önce sahip olduğum 9999 satırı yok.

Herkes şikayet etmeden önce, evet bu soruları okudum. Yukarıda listelenen önerilerinin bir kısmını uyguladım, geri kalanı yararsızdı veya ilgisizdi:

İçinde başka ilgili komutlar olması ihtimaline karşı, tümümüzü ~/.bashrc burada görebilirsiniz .

O zaman neyi özlüyorum? Geçmişim neden kaydedilmedi? Herkes başka bir dosyanın ilgili olabileceğini düşünürse bana bildirin, ben de gönderirim. Dize içeren tek ilgili dosya olduğunu gösterdi grep -i hist \.*benim çalışarak kontrol veya oldu .$HOME.histHIST.bashrc

Linux Mint Debian Edition, GNU bash, sürüm 4.2.36 (1) -release (x86_64-pc-linux-gnu) ve en sevdiğim terminal öykünücüsünü (ilgili olması durumunda) çalıştırıyorum terminator.


GÜNCELLEME:

@ Mpy'nin yorumlardaki önerisini takiben , varsayılanın aksine olarak ~/.bashrcayarlamamı değiştirdim ve bu etkileşimli kabuklar için sorunu çözüyor gibi görünüyor . Giriş kabukları hala aynı davranışı gösterir ve geçmiş satırlarda kesilir . Ancak, ilgili dosyalarda ayarlanmış ilişkili değişken yoktur :HISTFILE=~/bash_history~/.bash_history500HIST

$ for f in /etc/profile ~/.profile ~/.bash_profile ~/.bash_login; do \
   echo -ne "$f :"; echo `grep HIST $f`; \
done
/etc/profile :
/home/terdon/.profile :grep: /home/terdon/.profile: No such file or directory
/home/terdon/.bash_profile :grep: /home/terdon/.bash_profile: No such file or directory
/home/terdon/.bash_login :grep: /home/terdon/.bash_login: No such file or directory
$ grep -r HIST /etc/profile.d/  <-- returns nothing

Öyleyse, neden kuruyor HISTSIZEve HISTFILESIZEiçinde ~/.bashrcaçıkça ayarlanmış sürece yeterli değil $HISTFILEvarsayılan dışında bir şeye ~/.bash_history?


.Bash_history veya root sahibi misiniz? Yap ls -l .bash_history
Adnan Bhatti

1
@ MSStp evet, bana ait. Öneri için teşekkürler ama yine de nasıl bir izin sorunu olabileceğini görmüyorum, ya okuma / yazma erişimi var ya da ben yok. Yana bazı tarih kaydedilir, açıkça yok. Bash, bu dosya kullanıcı tarafından sahiplenilmediğinde sorunlara neden olan bir ayara sahipse, şikayet eder veya geçmiş işlevlerinin tümü çalışmaz.
terdon

historykomutu yürüttüğünüzde , gördüğünüz çıktı cat .bash_historysatır numaraları dışında gördükleriniz ile aynı mı? Yani historykomut listesi zaman damgaları veya diğer bilgiler mi? Sormamın nedeni, bu ezoterik şeyleri görürseniz, kabuk geçmişiyle uğraşan başka bir modül / fonksiyon / program olması ve ne olursa olsun yanlış veya buggy bir versiyonunun, kedere neden olabileceği anlamına geliyor. .
MelBurslan

@Mel_Burslan evet aynı, tek fark satır numaraları.
terdon

2
Tamam, biraz garip bir öneri, ama bu da garip bir sorun ;): Başka bir dosyayı varsayılan olarak değil HISTFILE olarak deneyin ~/.bash_history. Çok yapılandırılmış bir açıklama: Ben bash varsayılan kabuk olduğunu varsayalım, bu yüzden sistem başlatıldığında etkileşimli olmayan bir kabuk X oturumunuzun üst öğesi (ayrıca X kullandığınızı da varsayıyorum), histappend seçeneği hakkında hiçbir şey bilmeyecektir (.bashrc sadece Bu ana kabuk çalıştığı sürece her şey yolundadır, ancak sonlandırıldığında (yani sistem durduğunda) geçersiz kılar ~/.bash_history(varsayılan olarak) ve geçmişinizi
bozar

Yanıtlar:


17

Sorun aslında giriş ve giriş dışı mermilerin farklı davranışlarıyla ilgilidir. Tarihimi kontrol eden değişkenleri ayarlamıştım ~/.bahsrc. Bu dosya, bir giriş kabuğu başlatıldığında okunmaz, yalnızca etkileşimli, giriş yapmayan kabuklar (tarafından man bash) tarafından okunur :

Bash, etkileşimli bir giriş kabuğu veya --loginseçenekle etkileşimli olmayan bir kabuk olarak çağrıldığında /etc/profile, bu dosya varsa önce dosyadan komutları okur ve yürütür . Bu dosyayı okuduktan sonra ~ / .bash_profile, ~/.bash_loginve ~/.profilebu sırayla arar ve var olan ve okunabilir olan ilk komutları okur ve yürütür. Bu --noprofileseçenek, kabuk bu davranışı engellemek için başlatıldığında kullanılabilir.

[. . . ]

Oturum açma kabuğu olmayan bir etkileşimli kabuk başlatıldığında, bash bu dosya varsa ~ / .bashrc'den komutları okur ve yürütür. Bu, --norc seçeneği kullanılarak engellenebilir. --Rcfile dosyası seçeneği bash komutunu ~ / .bashrc yerine dosyadan okumaya ve yürütmeye zorlar.

Bu nedenle, her giriş yaptığımda veya bir tty'ye düştüğümde veya ssh kullandığımda, .historydosya da doğru boyuta ayarlamamışım nedeniyle kesiliyordu ~/.profile. Sonunda bunu fark ettim ve değişkenleri ~/.profile ait oldukları yere koymak yerine~/.bashrc

Bu yüzden, ~/.historykesilmemin nedeni, GEÇMİŞ değişkenlerini yalnızca etkileşimli, giriş yapmayan kabuklar tarafından okunan bir dosyada ayarlamış olduğum ve bu nedenle her farklı türde kabuk çalıştırdığımda değişkenler göz ardı edilecek ve dosya kesilecekti. buna göre.


Çok iyi bir nokta, paylaştığın için teşekkürler! Ancak, aynı fikirde değilim: Bir dosya bir giriş kabuğu başlattığında bu dosya okunmaz, sadece etkileşimli kabuklar tarafından okunur. Çünkü bir giriş kabuğu da etkileşimli olabilir. Aksi takdirde tüm tarih mekanizması hiçbir anlam ifade etmeyecektir. IMHO .bashrctarafından okunmuyor (etkileşimli olmayan VEYA giriş kabukları).
mpy

@mpy Gerçekten, üzgünüm, etkileşimli, giriş yapmayan mermiler demek istedim. Yanıt düzenlendi.
terdon

1
@terdon, ortak deyim, etkileşimli kabuk seçeneklerinin ~ / .profile veya ~ / .bash_profile'a girmemesidir. Etkileşimli kabuk seçenekleri ~ / .bashrc içine konur. Ayarları iki yerde tutmak zorunda kalmamak için aşağıdaki komutlar ~ / .bash_profile öğesinin en üstüne yerleştirilebilir: export BASH_ENV=~/.bashrc ; if [ -f ~/.bashrc ]; then . ~/.bashrc; fi... ve ~ / .bashrc öğesinin en üstüne gerçekten etkileşimli çalıştığınızdan emin olmak için bir onay işareti koyabilirsiniz: [ -z "$PS1" ] && return... Tabii ki, bu sadece bir deyim.
Noah Spurrier

1
@NoahSpurrier BASH_ENVilgili değildir, sadece etkileşimli olmayan mermileri etkiler. "Deyim" e gelince, Debian'ın başladığı ve şahsen kabul etmediğim bir şeydir . Sık sık xsetbenim .bashrc grafik seçenekleri ( ve benzeri) var ve ben bir tty veya aracılığıyla giriş kabukları çalıştırdığınızda bu aktif istemiyorum ssh. Ben istiyorum benim .profile dosyalarını ve ayrı Bashrc. Çoğu (hepsi olmasa da) oturum açma yöneticileri, global değişkenlerin en iyi orada ayarlandığı ve bir terminali her açışınızda değil, yalnızca bir kez okunacakları şekilde .profile kaynağına kaynak sağlar.
terdon

1
@WilsonF evet. Dosyalar sırayla okunur ve kişisel dosyalar ( ~/.profileveya ~/.bashrc) en son okunur. Bunlarda ayarlanan her şey, global ayarlardan öncelikli olacaktır. Çok haklısın, bu değişkenleri ayarlamamalısın /etc/bash.bashrc. Kullanın ~/.profile(veya ~/.bash_profile) yerine.
terdon

11

Benim önerim, HISTFILEvarsayılan olarak değil başka bir dosya kullanmaktır ~/.bash_history.

Analitik bir açıklamam olmamasına rağmen, beni bu öneriye neyin götürdüğünü özetlemeye çalışacağım: bashVarsayılan (giriş) kabuğunuz olarak kullanıyorsanız ve X(her ikisi de çok olası) kullanıyorsanız bash(grafiksel) hemen sonra çalışan bir örneğiniz var. ) oturum aç:

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

Bu örneğin bir giriş kabuğu olduğunu düşünüyorum, bu yüzden sizin okumaz ~/.bashrcve bu nedenle histappendseçenek hakkında hiçbir şey bilmez :

man bash (1) : Oturum açma kabuğu olmayan bir etkileşimli kabuk başlatıldığında, bash bu dosyalar varsa /etc/bash.bashrc ve ~ / .bashrc'deki komutları okur ve yürütür. (...)

Bu "ana kabuk" çalıştığı sürece, her şey yolundadır, ancak sonlandırıldığında (yani sistem durduğunda) geçersiz kılar ~/.bash_history(varsayılan değer olduğu için) ve geçmişinizi bozar veya sistem başlangıcında klipsler (tekrar varsayılan) 500 çizgiler. (Ya da belki ikisi de ...)

Bu kadar ~/.bashrcnadir bir kurulum olmamalı, tarih yapılandırmasını dahil etmenin yeterli olmadığına da dikkat çekiyor. Bunun için bir açıklamam yok.


"Giriş kabukları hala aynı davranışı gösteriyor" sorununuzla ilgili olarak, geçmiş yapılandırmasını şu adreslere de eklemeyi deneyebilirsiniz ~/.bash_profile:

man bash (1) : bash etkileşimli bir giriş kabuğu olarak veya --login seçeneğiyle etkileşimli olmayan bir kabuk olarak çağrıldığında, dosya varsa / etc / profilinden komutları okur ve yürütür. Bu dosyayı okuduktan sonra ~ / .bash_profile, (...)

Ne yazık ki bash, ben bir zsherkeğim olarak, kendi yapılandırmamdaki ayrıntılarla daha haklı bir açıklama gönderemiyorum ...


2
Açıkça benim geçmiş seçenekleri ayarlamak ~/.bash_profilesorunu çözdü. Şimdi ~/.bash_historygeçmiş dosyam olarak kullanıyorum , ancak ~/.bashrcsoruma gösterilen tüm satırları ekledim ~/.bash_profile. Hala etkileşimli kabukları kimin vidaladığını bilmiyorum, ama şimdi işe yarıyor gibi görünüyor, teşekkürler!
terdon

1
Kabul etmediğim için üzgünüm ama neler olduğunu açıklayan bir cevap göndermeyi unutmuştum. Bir süre önce @Gilles'dan biraz yardım aldım ve sonunda bir cevap göndermeye başladım. Benimkini kabul etmek istedim, çünkü (çok iyi) bir geçici çözüm sunmak yerine konuyu açıklıyor ve gelecekteki ziyaretçilere yardımcı olabilir.
terdon

2

Tüm ayarlarınız man sayfasına göre yapıldığından ve geçmiş dosyası boyut (bayt) ile kısıtlanmadığından, düşünebileceğim tek açıklama. Kabuğun nasıl öldüğü ile ilgilidir.

Çevrimiçi referansa göre, zarif çıkış (geçmiş kaydedildi) yalnızca kabuk SIGHUP aldığında gerçekleşir. Sisteminizin yeniden başlatıldığında sinyalleri nasıl yaydığını gerçekten açıklayamıyorum, ancak kabuğunuzun SIGKILL veya SIGPWR ile kapandığından şüpheleniyorum.

Bunun nedeni, WM'nizin senkronize olmayan bir şekilde çalışması (beklemek) ve bash'ın bulunduğu WM'den kaynaklanan terminal emülatörünün SIGHUP dışında bir çıkış zorlama sinyali alması olabilir. Ayrıca, ilk zarif SIGHUP, X -> WM -> xterm aracılığıyla kabuğa ulaşmayı başarmadan önce işletim sisteminin "son öldürmeyi" hızlı bir şekilde göndermesi olabilir, çünkü muhtemelen X veya WM'nin çıkması daha uzun sürer işletim sisteminin düşmeye hazır olması gerekir.

Bu şeylerle derin sulardayım, ama bu çizgiler boyunca bir şey düzensiz davranışlara neden olduğunu düşünüyorum. Bu sorunu daha önce yaşadım ve en sağlam çözüm, exittarihi tutmak istediğiniz bash'da.

Sorunuzda fark ettim history -ave bunun tarihi korumak için neden yeterli olmadığını düşünemiyorum.

Bash'ınızı gerçekten neyin öldürdüğünü anlayarak ve sinyalin nereden kaynaklandığını ve sorunun orada çözüldüğünü belirleyerek sorunu giderebilir veya en son hangi sinyalin olduğunu bildiğinizde geçmişi temizleyebilirsiniz (disklerin hala çevrimiçi olduğunu varsayarak) ):

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...

Birlikte verilen ekran görüntüsü, ikinci ve üçüncü paragraflarda neden bahsettiğimi gösterir. Ben de kabuk vardır dizisi soldan , sağdan ve kedi geçmişinden sol kabuk öldürür.

adam bash

Başlangıçta, (...) HISTFILE değerine göre adlandırılan dosya, gerekirse HISTFILESIZE (+ varsayılan 500) değerinde belirtilen satır sayısından fazlasını içermeyecek şekilde kesilir.

Histappend kabuk seçeneği etkinse (burada + varsayılan) satırlar geçmiş dosyasına eklenir, aksi takdirde geçmiş dosyasının üzerine yazılır.

çevrimiçi başvuru

3.7.6 Sinyaller

Bash etkileşimli olduğunda, herhangi bir tuzak olmadığında, SIGTERM'i yok sayar (böylece '0 öldür' etkileşimli bir kabuğu öldürmez) ve SIGINT yakalanır ve işlenir (böylece bekleme yerleşimi kesilebilir). Bash bir SIGINT aldığında, yürütme döngülerinden çıkar. Her durumda, Bash SIGQUIT'i yok sayar. İş kontrolü etkinse (bkz. İş Kontrolü), Bash SIGTTIN, SIGTTOU ve SIGTSTP'yi yok sayar.

Bash tarafından başlatılan yerleşik olmayan komutlar, sinyal işleyicilerinin kabuk tarafından üst öğesinden devralınan değerlere ayarlandığını gösterir. İş kontrolü etkin olmadığında, eşzamansız komutlar, bu devralınan işleyicilere ek olarak SIGINT ve SIGQUIT'i yok sayar. Komutların değiştirilmesi sonucunda çalışan komutlar, klavye tarafından oluşturulan SIGTTIN, SIGTTOU ve SIGTSTP iş denetim sinyallerini yoksayar.

Bir SIGHUP alındıktan sonra kabuk varsayılan olarak çıkar. Çıkıştan önce, etkileşimli bir kabuk SIGHUP'u çalışan veya durdurulmuş tüm işlere yeniden gönderir. Durdurulmuş işler SIGHUP aldıklarından emin olmak için SIGCONT'a gönderilir. Kabuğun SIGHUP sinyalini belirli bir işe göndermesini önlemek için, reddedilen yerleşik (bkz. Job Control Builtins) olan işler tablosundan kaldırılmalı veya -H disown kullanılarak SIGHUP alınmayacak şekilde işaretlenmelidir.

Huponexit kabuk seçeneği shopt ile ayarlanmışsa (bkz. Shopt Builtin), Bash etkileşimli bir giriş kabuğu çıktığında tüm işlere bir SIGHUP gönderir.

Bash bir komutun tamamlanmasını bekliyor ve tuzağı ayarlanmış bir sinyal alıyorsa, komut tamamlanıncaya kadar tuzak yürütülmez. Bash, wait yerleşimi üzerinden eşzamansız bir komut beklerken, bir tuzağın ayarlandığı bir sinyalin alınması, bekleme yerleşiminin hemen, tuzağın yürütülmesinden hemen sonra 128'den daha büyük bir çıkış durumu ile geri dönmesine neden olur.

açıklayıcı ekran görüntüsü

sinyalleri


Bu ekran görüntüsünde ne yaptığınızı gerçekten anlayamıyorum. Ne olduğunu /tmp/psosen öldürüyorsun o? Farklı öldürme sinyalleri hakkındaki görüşünüzü görüyorum (dediğiniz gibi history -a, bununla başa çıkmanın orada olduğunu düşündüm ). Bunu bir süre test edip rapor vereceğim.
terdon

$ cat tmp / ps * \ n ps -o pid = | head -n1> ~ / tmp / pso \ n 17201 \ n
Ярослав Рахматуллин

0

/ Etc / profile ve /etc/profile.d/* 'yi kontrol edin

Belki de tarih ayarlarıyla uğraşan bir şey var.


Teşekkürler, ama grep -r HIST /etc/profile.d/hiçbir şey döndürmez ve ben zaten kontrol ettim /etc/profile.
terdon
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.