2008-12-03 10 views
38

मैं bash को मेरे इतिहास में डुप्लिकेट कमांड सहेजने से रोकने की कोशिश कर रहा हूं। यहाँ मैं क्या कर लिया है:बैश इतिहास में डुप्लिकेट को सहेजने से रोकें

shopt -s histappend 
export HISTIGNORE='&:ls:cd ~:cd ..:[bf]g:exit:h:history' 
export HISTCONTROL=erasedups 
export PROMPT_COMMAND='history -a' 

यह ठीक काम करता है, जबकि मैं में लॉग इन कर रहा हूँ और .bash_history स्मृति में है। उदाहरण के लिए:

$ history 
    1 vi .bashrc 
    2 vi .alias 
    3 cd /cygdrive 
    4 cd ~jplemme 
    5 vi .bashrc 
    6 vi .alias 

$ vi .bashrc 

$ history 
    1 vi .alias 
    2 cd /cygdrive 
    3 cd ~jplemme 
    4 vi .alias 
    5 vi .bashrc 

$ vi .alias 

$ history 
    1 cd /cygdrive 
    2 cd ~jplemme 
    3 vi .bashrc 
    4 vi .alias 

$ exit 

लेकिन जब मैं वापस में प्रवेश करें, अपने इतिहास फ़ाइल इस तरह दिखता है:

$ history 
    1 vi .bashrc 
    2 vi .alias 
    3 cd /cygdrive 
    4 cd ~jplemme 
    5 vi .bashrc 
    6 vi .alias 
    7 vi .bashrc 
    8 vi .alias 

क्या मैं गलत कर रहा हूँ?

संपादित करें: और PROMPT_COMMAND.bashrc से लाइनों को समस्या को ठीक नहीं करता है।

+1

क्या आपने कभी इसे हल किया है? मेरा/etc/प्रोफ़ाइल इस तरह दिखता है (मैक पर) और मुझे एक ही समस्या है: # http://blog.macromates.com/2008/working-with-history-in-bash/ # http: //www.ducea.com/2006/05/15/linux-tips-take-control-of-your-bash_history/ निर्यात HISTCONTROL = erasedups निर्यात HISTSIZE = 10000 निर्यात HISTTIMEFORMAT = "% F-% टी% टी " shopt -s histappend (यह आधा सभ्य, नहीं आसान फ़ॉर्मेट करने के लिए कोशिश कर रहा है) – joedevon

+0

इस सवाल http://unix.stackexchange.com/questions/48713/how-can-i-remove-duplicates देखें -इन-माय-बैश-इतिहास-संरक्षण-आदेश – Nathan

+1

यह प्रोग्रामिंग में विशिष्ट समस्या है और विशिष्ट उपकरण प्रोग्रामर उपयोग से संबंधित है। मुझे रहस्य है कि इस प्रश्न को "ऑफ-विषय" माना जाएगा (कम से कम 5 लोगों द्वारा अधिक)। एक अनावश्यक .bash_history अब हल करने के लिए एक लंबी परेशानी है। हालांकि यह प्रश्न यूनिक्स स्टैकएक्सचेंज साइट पर ले जाया जा सकता है। –

उत्तर

7

समस्या निश्चित रूप से histappend है। परीक्षण और मेरी प्रणाली पर पुष्टि की।

मेरे प्रासंगिक वातावरण है:

$ set | grep HIST 
HISTFILE=/Users/hop/.bash_history 
HISTFILESIZE=500 
HISTIGNORE=' *:&:?:??' 
HISTSIZE=500 
$ export HISTCONTROL=erasedups 
$ shopt | grep hist 
cmdhist   on 
histappend  off 
histreedit  off 
histverify  off 
lithist   off 

अब मैं इसके बारे में लगता है कि यह समस्या शायद history -a के साथ है। history -w को किसी भी डुप्लीकेट के बिना वर्तमान इतिहास लिखना चाहिए, इसलिए यदि आप समवर्ती मुद्दों पर ध्यान नहीं देते हैं तो इसका उपयोग करें।

2

यहाँ .. मैं क्या उपयोग है

[[email protected] ~]$ grep HIST .alias* 
.alias:HISTCONTROL="erasedups" 
.alias:HISTSIZE=20000 
.alias:HISTIGNORE=ls:ll:"ls -altr":"ls -alt":la:l:pwd:exit:mc:su:df:clear:ps:h:history:"ls -al" 
.alias:export HISTCONTROL HISTSIZE HISTIGNORE 
[[email protected] ~]$ 

और

[[email protected] ~]$ pwd 
/Users/XXX 
[[email protected] ~]$ pwd 
/Users/XXX 
[[email protected] ~]$ history | grep pwd | wc -l 
     1 
+2

धन्यवाद वेनु। मेरी समस्या यह है कि थोड़ा अलग है। मान लें कि इतिहास में 20 "एलएस" हैं। "एलएस" टाइप करके, यह डुप्लिकेट को हटा देता है ताकि कम से कम सत्र के दौरान आपका इतिहास छोटा हो .... लेकिन बाहर निकलें और एक नया सत्र शुरू करें और यह नई चीजें बचाता है और पुराने डुप्लिकेट को बरकरार रखता है। Erasedups की अधिकांश उपयोगिता पूर्ववत करना। #Facepalm। – joedevon

+0

मेरे .bash_profile के समान कुछ जोड़ा गया: 'निर्यात HISTIGNORE = ls:" ls -la ":" cd .. ":" cd ~ ": pwd: exit: su:" sudo -i ": clear: ps: "पीएस $ निर्यात HISTSIZE = 20000 निर्यात HISTCONTROL =" erasedups "' – humbolight

1

अपने .bash_profile अंदर काम कर जोड़ने

alias hist="history -a && hist.py" 

तो hist.py के रूप में अपने रास्ते पर इस डाल दिया और इसे निष्पादन योग्य बनाएं

#!/usr/bin/env python 
f = open('/Users/joe/.bash_history') 
l = f.readlines() 
l.reverse() 
short = [] 
for s in l: 
    if s.rstrip() not in short: 
     short.append(s.rstrip()) 
short.reverse() 
for s in short: 
    print s 

अब आप संक्षिप्त सूची सिर्फ टाइप चाहते हैं जब hist

31

जहाँ तक मुझे पता है, यह तुम क्या चाहते करने के लिए संभव नहीं है। मैं इसे बैश के इतिहास प्रसंस्करण में एक बग के रूप में देखता हूं जिसे बेहतर किया जा सकता है।

export HISTCONTROL=ignoreboth:erasedups # no duplicate entries 
shopt -s histappend      # append history file 
export PROMPT_COMMAND="history -a"  # update histfile after every command 

यह स्मृति के इतिहास में अद्वितीय रखेंगे, लेकिन जब यह होता है एक ही फाइल में अनेक सत्रों से इतिहास को सहेजता है, यह फ़ाइल स्वयं अद्वितीय में इतिहास नहीं रखता। history -a फ़ाइल में नया आदेश तब तक लिख देगा जब तक कि यह तुरंत उसके जैसा ही नहीं होता है। यह स्मृति में erasedups सेटिंग की तरह पूर्ण डी-डुप्लिकेशन नहीं करेगा।

कार्रवाई में इस शांतता को देखने के लिए, एक नया टर्मिनल सत्र शुरू करें, इतिहास की जांच करें, और आप ls कहें, बार-बार प्रविष्टियां देखेंगे। अब ls कमांड चलाएं, और सभी डुप्लिकेट ls को स्मृति में इतिहास से निकाल दिया जाएगा, केवल अंतिम को छोड़कर। स्मृति इतिहास में छोटा हो जाता है क्योंकि आप इतिहास फ़ाइल में डुप्लिकेट किए गए आदेश चलाते हैं, फिर भी इतिहास फ़ाइल स्वयं बढ़ती जा रही है।

मैं मांग पर इतिहास फ़ाइल को साफ करने के लिए अपनी खुद की स्क्रिप्ट का उपयोग करता हूं।

# remove duplicates while preserving input order 
function dedup { 
    awk '! x[$0]++' [email protected] 
} 

# removes $HISTIGNORE commands from input 
function remove_histignore { 
    if [ -n "$HISTIGNORE" ]; then 
     # replace : with |, then * with .* 
     local IGNORE_PAT=`echo "$HISTIGNORE" | sed s/\:/\|/g | sed s/\*/\.\*/g` 
     # negated grep removes matches 
     grep -vx "$IGNORE_PAT" [email protected] 
    else 
     cat [email protected] 
    fi 
} 

# clean up the history file by remove duplicates and commands matching 
# $HISTIGNORE entries 
function history_cleanup { 
    local HISTFILE_SRC=~/.bash_history 
    local HISTFILE_DST=/tmp/.$USER.bash_history.clean 
    if [ -f $HISTFILE_SRC ]; then 
     \cp $HISTFILE_SRC $HISTFILE_SRC.backup 
     dedup $HISTFILE_SRC | remove_histignore >| $HISTFILE_DST 
     \mv $HISTFILE_DST $HISTFILE_SRC 
     chmod go-r $HISTFILE_SRC 
     history -c 
     history -r 
    fi 
} 

मुझे ऐसा करने के लिए और अधिक शानदार तरीके सुनना अच्छा लगेगा।

नोट: यदि आप HISTTIMEFORMAT के माध्यम से इतिहास में टाइमस्टैम्प सक्षम करते हैं तो स्क्रिप्ट काम नहीं करेगी।

बैश के लिए द्वारा

  1. ठीक history -a स्थिति में सुधार केवल नए डेटा लिखने अगर यह न सिर्फ पिछले एक स्मृति में किसी भी इतिहास से मेल नहीं खाता, कर सकते हैं।
  2. erasedups सेटिंग सेट होने पर फ़ाइलों को पढ़े जाने पर इतिहास को de-deduplicate इतिहास सेट करें। एक नए टर्मिनल में एक सरल history -w तब ऊपर की मूर्खतापूर्ण लिपि की बजाय इतिहास फ़ाइल को साफ़ कर देगा।
+3

उत्कृष्ट उत्तर। यदि आप अपने आदेशों के लिए क्रमिक क्रम (इनपुट ऑर्डर के बजाए) को संरक्षित करना चाहते हैं, तो 'awk' को बदलकर 'dedup() 'को संशोधित करें। ! x [$ 0] 'tac $ @ | awk 'के साथ ++' $ @'! x [$ 0] ++ '| tac'। – trusktr

+6

@raychi बस यह देखने के लिए जांच कर रहा है, अगर यह 2014 तक पहुंचने के बाद भी यह सबसे अच्छा समाधान है –

+1

@ trusktr की टिप्पणी को विस्तारित करने के लिए, 'इतिहास-ए' को केवल नए डेटा को लिखने के लिए ठीक नहीं किया जाएगा, क्योंकि यह वास्तव में पिछली घटना को हटा देना चाहिए और नवीनतम जोड़ना चाहिए। मुझे संदेह है कि यह इस जटिलता के कारण है कि वे ' हम लगातार डुप्लीकेट हटाने के लिए बस गए हैं। – trss