it-swarm-tr.com

Bash geçmişi: "yok sayılanlar" ve "silinenler", oturumlar boyunca ortak geçmişle çakışıyor

Her şeyden önce, bu SE üzerinde mevcut herhangi bir iş parçacığının kopyası değildir. Daha iyi bash tarihinde bu iki konu ( 1st , 2nd ) okudum, ama cevapların hiçbiri işe yaramaz - - Bu arada Fedora 15 duyuyorum.

Aşağıdakileri .bashrc dizinini kullanıcı dizininde (/ home/aahan /) kullanır ve çalışmaz. Kimsenin ipucu var mı?

HISTCONTROL=ignoredups:erasedups  # no duplicate entries
HISTSIZE=1000                     # custom history size
HISTFILESIZE=100000                 # custom history file size
shopt -s histappend                      # append to history, don't overwrite it
Prompt_COMMAND="history -a; history -c; history -r; $Prompt_COMMAND"  # Save and reload the history after each command finishes

Tamam bash geçmişi (öncelik) ile istediğim bu:

  • kopyaları saklamayın, mevcut olanları silin
  • geçmişi tüm açık terminallerle anında paylaşın
  • her zaman tarih ekleyin, üzerine yazmayın
  • çok satırlı komutları tek bir komut olarak depola (varsayılan olarak kapalıdır)
  • varsayılan Geçmiş boyutu ve geçmiş dosyası boyutu nedir?
92
its_me

Sor komutunuzda, -c değiştirmek. man bash:

- c Tüm girişleri silerek geçmiş listesini temizle

Geçmişinizi tüm açık terminallerle paylaşmak için -n:

- n Geçmiş dosyasından henüz okunmamış geçmiş satırlarını geçerli geçmiş listesine okuyun. Bunlar, geçerli bash oturumunun başlangıcından beri geçmiş dosyasına eklenen satırlardır.

Varsayılan boyut kılavuzda da bulunur:

HISTSIZE Komut geçmişinde hatırlanması gereken komut sayısı (aşağıdaki TARİH'e bakın). Varsayılan değer 500'dür.

Çok satırlı komutları kaydetmek için:

cmdhist Kabuk seçeneği, etkinleştirilirse, Kabuğun çok satırlı bir komutun her satırını aynı geçmiş girdisine kaydetmeye çalışarak sözdizimsel doğruluğu korumak için gereken noktalara noktalı virgül ekler. lithist Kabuk seçeneği, Kabuk'un komutu noktalı virgül yerine katıştırılmış yeni satırlarla kaydetmesine neden olur.

Ayrıca, HIST * komutlarını export ile önceden yazmamalısınız - bunlar çevresel değişkenler değil yalnızca bash değişkenleridir: HISTCONTROL=ignoredups:erasedups yeterlidir.

8
jasonwryan

Ben de öyle geldim ve şimdiye kadar bundan memnunum…

alias hfix='history -n && history | sort -k2 -k1nr | uniq -f1 | sort -n | cut -c8- > ~/.tmp$$ && history -c && history -r ~/.tmp$$ && history -w && rm ~/.tmp$$'  
HISTCONTROL=ignorespace  
shopt -s histappend  
shopt -s extglob  
HISTSIZE=1000  
HISTFILESIZE=2000  
export HISTIGNORE="!(+(*\ *))"  
Prompt_COMMAND="hfix; $Prompt_COMMAND" 

NOTLAR:

  • Evet, karmaşık ... ama tüm kopyaları kaldırıyor ve yine de her terminaldeki kronolojiyi koruyor!
  • HISTIGNORE değişkenim olmayan tüm komutları yok sayar. Bu, bazı kişiler tarafından istenmeyebilir ve dışarıda bırakılabilir.
8
user41176

Bunun yerine şunu kullanın:

HISTCONTROL=ignoreboth
1
verndog

Çalışmıyor, çünkü unutuyorsunuz:

 -n   read all history lines not already read from the history file
      and append them to the history list

Ancak, history -n Yürürlükte olduğunda export HISTCONTROL=ignoreboth:erasedups Buggy gibi görünüyor.

Deney yapalım:

$ Prompt_COMMAND=
$ export HISTCONTROL=ignoreboth:erasedups
$ export HISTFILE=~/.bash_myhistory
$ HISTIGNORE='history:history -w'
$ history -c
$ history -w

Burada çiftleri silmeyi açıyoruz, geçmişi özel dosyaya geçiriyoruz, geçmişi temizliyoruz. Tüm komutlar tamamlandıktan sonra boş geçmiş dosyası ve geçerli geçmişte bir komut var.

$ history
$ cat ~/.bash_myhistory
$ history
$ 1  [2019-06-17 14:57:19] cat ~/.bash_myhistory

İkinci terminali açın ve bu altı komutu da çalıştırın. Daha sonra:

$ echo "X"
$ echo "Y"
$ history -w
$ history
  1  [2019-06-17 15:00:21] echo "X"
  2  [2019-06-17 15:00:23] echo "Y"

Şu anki geçmişinizde iki komut var ve geçmiş dosyanız:

#1560772821
echo "X"
#1560772823
echo "Y"

İlk terminale geri dön:

$ history -n
$ history
1  [2019-06-17 14:57:19] cat ~/.bash_myhistory 
2  [2019-06-17 15:03:12] history -n

Ha ... echo komutunun hiçbiri okunmuyor. Tekrar ikinci terminale geçin ve:

$ echo "Z"
$ history -w

Şimdi geçmiş dosyası:

#1560772821
echo "X"
#1560772823
echo "Y"
#1560773057
echo "Z"

İlk terminale tekrar geçin:

$ history -n
$ history
  1  [2019-06-17 14:57:19] cat ~/.bash_myhistory 
  2  [2019-06-17 15:03:12] history -n
echo "Z"

echo "Z" Komutunun history -n İle birleştirildiğini görebilirsiniz.

Başka bir bug komutları geçmişinden komut numarası ile değil, komut zamanı tarafından okunması nedeniyle düşünüyorum. Başkalarının echo komutlarının geçmişte görünmesini bekliyorum

0
Eugen Konkov

Burada cevapların bir kombinasyonu ile gittim:

  • Geçmişimin sonunda birleştirilmesini istiyorum, bu yüzden tuzak işlevini kullandım.
  • Ayrıca geçmiş dosyalarımı ana bilgisayarlar tarafından ayrılmış olmasını istiyorum, bu yüzden ana bilgisayar adına bağlı olarak bir dizini ve adlandırılmış dosyaları işaret edecek şekilde HISTFILE değiştirdim.
  • Açık metin parolaları yazabileceğim ve bunların geçmişte görünmelerini sağlayamayacağım için yoksayma seçeneği ekledim, örneğin: $ ./.secretfunction -user myuser -password mypassword boşlukla başladığı için kaydedilmeyecek.
  • Ekledim history* ve exit ile HISTIGNORE arasında yalnızca geçmiş gibi history | grep awesomecommand normalde ben istemez beri oradan. Diğerlerini ekleyebilirsiniz: oturum kapatma, fg, bg, vb.
  • Daha sonra hepsini ~/.bash_aliases dosyama koydum, bu yüzden bazen olduğu gibi yükseltmelerle çelişmiyor.
HISTCONTROL=ignoreboth:erasedups:ignorespace
HISTIGNORE="history*:exit"
HISTFILE=~/.bash_history/.$(hostname)_history
shopt -s histappend
function historymerge {
    history -n; history -w; history -c; history -r;
}
trap historymerge EXIT
Prompt_COMMAND="history -a; $Prompt_COMMAND"

Geçmişi -a ile değiştirilmeden emin olmak için ~/için Prompt_COMMAND anahtarınızı kullanın. Ayrıca TIME/DATE biçimini HISTTIMEFORMAT="%x %r %Z " Sevdim ama yerel duyarlı olduğundan yukarıdaki blok dahil etmedi.

0
Marlon

silme işlemleri önde gelen ve sondaki boşlukları kırpmaz (bazı dillerde chomp gibi). Bu bir hatadır. Ayrıca silme işlemleri önceki tüm girişleri silmez.

0

@ Rozcietrzewiacz'in 3. seçeneği ile bir çıkış tuzağının bir kombinasyonunun kullanılması, kapanışta yakınlaşan kendi bağımsız geçmiş oturumlarını sürdüren terminalleri etkinleştirir. Uzak bir ana dizini paylaşan farklı makinelerde birden fazla oturumla bile iyi çalışıyor gibi görünüyor.

export HISTSIZE=5000
export HISTFILESIZE=5000
export HISTCONTROL=ignorespace:erasedups
shopt -s histappend
function historymerge {
    history -n; history -w; history -c; history -r;
}
trap historymerge EXIT
Prompt_COMMAND="history -a; $Prompt_COMMAND"
  • historymerge işlevi, oturum dışı satırları geçmiş dosyasından yükler, bunları oturum geçmişi ile birleştirir, yeni bir geçmiş dosyası tekilleştirme ile yazar (böylece önceden eklenmiş yinelenen satırları ezer) ve geçmişi yeniden yükler.

  • history -a komut isteminde her komutta veri tekilleştirme olmadan geçmiş dosyasını güncellediğinden, geçmişi kaybetme potansiyelini en aza indirir.

  • Son olarak, tuzak historymerge oturum kapatmayı güncel bir temiz geçmiş dosyası için tetikler ve en son kapatılan oturumun komutları dosyanın sonuna kadar köpürür (sanırım).

Bununla, her terminal oturumunun lansmandan başlayarak kendi bağımsız geçmişi olacak. Farklı görevler için farklı terminallere açık olma eğiliminde olduğum için daha kullanışlı buluyorum (böylece her birinde farklı komutları tekrarlamak istiyorum). Ayrıca, sürekli olarak sıralı geçmişlerini dağıtılmış bir şekilde yeniden senkronize etmeye çalışan birden fazla terminalin anlamını yapmak çok daha basittir (yine de bunu seçili oturumlarla historymerge işlevini kullanarak kasıtlı olarak yapabilirsiniz veya hepsi).

Boyut sınırlarınızın istenen geçmiş uzunluğunu tutacak kadar büyük olmasını istediğinizi unutmayın artı tüm eşzamanlı olarak aktif oturumlar tarafından eklenebilecek tekilleştirilmemiş satırların hacmi. 5000, spam içerikli düşük değerli komutları filtrelemek için geniş kapsamlı HISTIGNORE kullanımı sayesinde benim için yeterli.

0
HonoredMule