बैश इतिहास: "अनदेखा" और "मिटाए गए" सत्रों के दौरान सामान्य इतिहास के साथ संघर्ष की स्थापना


84

सबसे पहले, यह एसई पर किसी भी मौजूदा थ्रेड्स का डुप्लिकेट नहीं है। मैंने इन दोनों थ्रेड्स ( 1 , 2 ) को बेहतर बैश इतिहास पर पढ़ा है , लेकिन कोई भी जवाब काम नहीं करता है - - मैं फेडोरा 15 रास्ते में हूं।

मैंने .bashrcउपयोगकर्ता निर्देशिका (/ home / aahan /) में फ़ाइल में निम्नलिखित जोड़ा है , और यह काम नहीं करता है। किसी के पास कोई सुराग है?

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

ठीक है कि मैं बैश इतिहास (प्राथमिकता) के साथ यही चाहता हूं:

  • डुप्लिकेट को संग्रहीत न करें, किसी भी मौजूदा को मिटा दें
  • सभी खुले टर्मिनलों के साथ तुरंत इतिहास साझा करें
  • हमेशा इतिहास को आगे बढ़ाएं, इसे अधिलेखित न करें
  • एकल आदेश के रूप में बहु-पंक्ति कमांड स्टोर करें (जो डिफ़ॉल्ट रूप से बंद है)
  • डिफ़ॉल्ट इतिहास आकार और इतिहास फ़ाइल आकार क्या है?

टक्कर! किसी को? कुछ भी काम नहीं करता है। क्या यह फेडोरा 15 (ग्नोम 3 के साथ और विंडोज होस्ट वर्चुअल मशीन पर चलने) के साथ एक समस्या हो सकती है?
इसका_मे its

कृपया यहां "टक्कर" पोस्ट न करें। यदि उन्हें उत्तर नहीं दिया जा रहा है तो आपको अधिक स्पष्ट रूप से पूछने की आवश्यकता है, संदर्भ सुराग के सही बिट्स, या कुछ शामिल करें। यदि आपको अपने पदों पर ध्यान देने की आवश्यकता है तो आप ऐसे बाउंस जारी कर सकते हैं जो अधिक लोगों को उन्हें अधिक ध्यान देने में मदद करें।
कालेब

1
क्या आप वाकई बैश का उपयोग कर रहे हैं? ( echo $SHELL)। यदि आप उन्हें अपने खुले शेल से मैन्युअल रूप से चलाते हैं तो क्या सेटिंग्स काम करती हैं? जाहिर है कि जब से वे इतने सारे लोगों के लिए काम करते हैं, तो सेटिंग्स सही हैं, आप उन्हें गलत तरीके से लागू कर रहे हैं। और कोई Fedora15 / Gnome3 / एक वर्चुअल मशीन होने का वास्तविक कार्य से कोई लेना-देना नहीं है bash
कालेब

@ कालेब, पोस्ट को टक्कर देने के बारे में पहले क्षमा करें। साथ ही, मैंने बहुत स्पष्ट होने की पूरी कोशिश की। नहीं, मैंने उन्हें शेल में जारी नहीं किया है। मैंने अभी उन्हें .bashrcफाइल में कॉपी-पेस्ट किया है। क्या वह गलत है? क्या आप वास्तविक शेल कमांड के साथ इस पोस्ट में "उत्तर" जोड़ सकते हैं? (कृपया मेरे noob-ity के साथ सहन करें।)
its_me

1
सब कुछ आप स्क्रिप्ट में लिखते .bashrcहैं या वास्तविक शेल कमांड होते हैं। लिपियों केवल शेल कमांड की श्रृंखला है। इसके अलावा आपने हाल ही में exportबिट को हटाकर जो एडिट किया था वह एक बुरा विचार था, जिसे रखा जाना चाहिए।
कालेब

जवाबों:


119

यह वास्तव में एक बहुत ही दिलचस्प व्यवहार है और मैं मानता हूं कि मैंने शुरुआत में इस सवाल को बहुत कम आंका है। लेकिन पहले तथ्य:

1. क्या काम करता है

कार्यक्षमता को कई तरीकों से प्राप्त किया जा सकता है, हालांकि प्रत्येक अलग तरह से काम करता है। ध्यान दें कि, प्रत्येक मामले में, इतिहास को दूसरे टर्मिनल (अद्यतन) में "स्थानांतरित" करने के लिए, किसी को Enterटर्मिनल में प्रेस करना होगा, जहां वह इतिहास को पुनः प्राप्त करना चाहता है।

  • विकल्प 1:

    shopt -s histappend
    HISTCONTROL=ignoredups
    PROMPT_COMMAND="history -a; history -n; $PROMPT_COMMAND"
    

    इसकी दो कमियां हैं:

    1. लॉगिन (एक टर्मिनल खोलना) पर, इतिहास फ़ाइल से अंतिम कमांड वर्तमान टर्मिनल के इतिहास बफर में दो बार पढ़ा जाता है;
    2. विभिन्न टर्मिनलों के बफ़र्स इतिहास फ़ाइल के साथ सिंक में नहीं रहते हैं।
  • विकल्प 2:

    HISTCONTROL=ignoredups
    PROMPT_COMMAND="history -a; history -c; history -r; $PROMPT_COMMAND"
    

    (हां, इसकी कोई आवश्यकता नहीं है shopt -s histappendऔर हां, इसके बीच में होना चाहिए ) इस संस्करण में दो महत्वपूर्ण कमियां भी हैं:history -cPROMPT_COMMAND

    1. इतिहास फ़ाइल को इनिशियलाइज़ करना होगा। इसमें कम से कम एक गैर-रिक्त रेखा (कुछ भी हो सकती है) शामिल है।
    2. historyआदेश झूठी उत्पादन दे सकते हैं - नीचे देखें।

[संपादित करें] "और विजेता है ..."

  • विकल्प 3:

    HISTCONTROL=ignoredups:erasedups
    shopt -s histappend
    PROMPT_COMMAND="history -n; history -w; history -c; history -r; $PROMPT_COMMAND"
    

    यह उतना ही है जितना इसे मिलता है। यह एक ही विकल्प है कि दोनों erasedupsऔर आम इतिहास एक साथ काम करें। यह शायद आपकी सभी समस्याओं का अंतिम समाधान है, अहान।


2. विकल्प 2 काम क्यों नहीं करता है (या: क्या वास्तव में अपेक्षित रूप से काम नहीं करता है)?

जैसा कि मैंने उल्लेख किया है, उपरोक्त समाधानों में से प्रत्येक अलग तरीके से काम करता है। लेकिन कमांड के आउटपुट का विश्लेषण करने से सेटिंग का काम कैसे होता है, इसकी सबसे भ्रामक व्याख्याhistory । कई मामलों में, कमांड गलत आउटपुट दे सकती है । क्यों? क्योंकि इसमें निहित अन्य आदेशों के अनुक्रम से पहले इसे निष्पादित historyकिया जाता है PROMPT_COMMAND! हालांकि, दूसरे या तीसरे विकल्प का उपयोग करते समय, कोई .bash_historyसामग्री के परिवर्तनों ( watch -n1 "tail -n20 .bash_history"उदाहरण के लिए) का उपयोग कर सकता है और देख सकता है कि वास्तविक इतिहास क्या है।

3. विकल्प 3 इतना जटिल क्यों है?

यह सब erasedupsकाम करने के तरीके में निहित है । जैसा कि बैश मैनुअल में कहा गया है, "(...) erasedupsउस लाइन को सहेजे जाने से पहले इतिहास की सूची से हटाए जाने वाली वर्तमान लाइन से मेल खाती सभी पिछली लाइनों का कारण बनता है" । तो यह वास्तव में वही है जो ओपी चाहता था (और न सिर्फ, जैसा कि मैंने पहले सोचा था, अनुक्रम में दिखाई देने वाले डुप्लिकेट नहीं हैं ) । यहां बताया गया है कि प्रत्येक history -.कमांड के पास या तो नहीं है PROMPT_COMMAND:

  • history -n है वहाँ से पहले history -wसे पढ़ने के लिए .bash_historyआदेशों किसी अन्य टर्मिनल से बचा लिया,

  • history -w है क्रम में फाइल और डुप्लिकेट को मिटाने के लिए इतिहास को बचाने के लिए वहाँ रहना,

  • history -a इसके स्थान पर नहीं रखा जाना चाहिएhistory -w , क्योंकि यह डुप्लिकेट को मिटाकर ट्रिगर नहीं करता है,

  • history -cयह भी आवश्यक है क्योंकि यह प्रत्येक कमांड के बाद इतिहास बफर को ट्रैश करने से रोकता है,

  • और अंत में, history -rहै की जरूरत फ़ाइल से इतिहास बफर बहाल करने के लिए, इस प्रकार अंत में इतिहास टर्मिनल सत्र के पार साझा बना रही है।


2
+1 के लिए "लेकिन इतिहास कमांड के आउटपुट का विश्लेषण करने से सेटिंग का काम कैसे होता है, इसकी सबसे भ्रामक व्याख्या।" मुझे लगता है कि यह ओपी के मुद्दे का मूल है। उत्कृष्ट कटौती।
जसोनव्रीयन

2
मैंने आखिरकार आपकी बात देखी। By डुप्लिकेट ’से आपका मतलब खुद से कुछ और था। मैंने केवल उसी कमांड के दृश्यों पर ध्यान केंद्रित किया । मेरा उत्तर अपडेट किया गया - "विकल्प 3" देखें। इसके अलावा, आपके मामले के लिए, यह परीक्षण करने के लिए कि इतिहास आपको कैसे काम करता है, watch "tail -n 20 .bash_history"इसके बजाय वास्तव में उपयोग करना चाहिए tail -f .bash_history
rozcietrzewiacz

2
विकल्प 3 बस (बैश 3.2.25 (1) -release) इतिहास की मेरी 100,000 लाइनों के सभी का सफाया :(
फेलिप अल्वारेज़

2
history -cयह भी आवश्यक है क्योंकि यह प्रत्येक आदेश के बाद इतिहास बफ़र को ट्रैश करने से रोकता है। यह ट्रैशिंग क्यों होता है?
पियोट्र डोब्रोगॉस्ट

2
आपका समाधान 3 वास्तव में काम नहीं करता है। यह बहुत छोटी गाड़ी है और इस आदेश पर निर्भर है कि उपयोगकर्ता विभिन्न टर्मिनलों में प्रवेश करते हैं। यह अक्सर खोए हुए आदेशों का परिणाम देगा, खासकर जब टर्मिनलों के बीच आगे और पीछे स्विच करना। स्रोत: इसे आज़माया
6cef

8

अपने प्रॉम्प्ट कमांड में, आप -cस्विच का उपयोग कर रहे हैं । से man bash:

-सभी   प्रविष्टियों को हटाकर इतिहास सूची को साफ़ करें

अपने इतिहास को सभी खुले टर्मिनलों के साथ साझा करने के लिए, आप इसका उपयोग कर सकते हैं -n:

-n   इतिहास फ़ाइल को वर्तमान इतिहास सूची में पहले से पढ़ी गई इतिहास पंक्तियों को न पढ़ें। ये वर्तमान बैश सत्र की शुरुआत के बाद से इतिहास फ़ाइल में संलग्न हैं।

डिफ़ॉल्ट आकार मैनुअल में भी है:

HISTSIZE कमांड इतिहास में याद रखने के लिए कमांड की संख्या (नीचे देखें इतिहास)। डिफ़ॉल्ट मान 500 है।

बहु-पंक्ति आदेशों को सहेजने के लिए:

Cmdhist खोल विकल्प, यदि सक्षम, अर्धविराम जहां आवश्यक वाक्यात्मक शुद्धता बनाए रखने के लिए जोड़ने, एक ही इतिहास प्रविष्टि में एक बहु लाइन आदेश की प्रत्येक पंक्ति को बचाने के लिए प्रयास करने के लिए खोल कारण बनता है। Lithist खोल विकल्प अर्धविराम बजाय एम्बेडेड नई-पंक्तियों के साथ आदेश को बचाने के लिए खोल कारण बनता है।

इसके अलावा, आपको HIST * कमांड को पहले से प्रस्तुत नहीं करना चाहिए export- वे बैश-केवल वैरिएबल हैं जो पर्यावरण चर नहीं हैं: HISTCONTROL=ignoredups:erasedupsपर्याप्त है।


तो, यह export PROMPT_COMMAND="history -a; history -n; history -r; $PROMPT_COMMAND"सही है? इसके अलावा, क्या आप जानते हैं कि मैं इतिहास फाइल स्टोर को मल्टी-कमांड को सिंगल कमांड के रूप में कैसे बना सकता हूं (जो डिफ़ॉल्ट रूप से बंद है) ??
its_me

1
हाँ। ऊपर उद्धृत मैन पेज के अनुसार, shopt -s cmdhistबहु-लाइनों को बचाएगा।
jasonwryan

ठीक है, मैंने उन्हें सब आजमाया। लगता HISTCONTROL=ignoredups:erasedupsहै काम नहीं कर रहा है। मैं भी .bashrcफ़ाइल में (कस्टम कार्यों के बीच) होने की कोशिश की । कोई अंदाजा क्या गलत हो सकता है? मैं एक आभासी मशीन पर फेडोरा 15 का उपयोग कर रहा हूं - - विंडोज 7 होस्ट।
its_me

सुनिश्चित करें कि अन्य स्टार्टअप फ़ाइलों में कुछ भी नहीं है, जैसे /etc/bashrc, .bash_profileआदि जो इसे ओवरराइड कर रहा है।
जसोनव्रीयन

मैं .bash_profileफ़ाइल के साथ कोई समस्या नहीं देखता । सामग्री के लिए के रूप में /etc/bashrcमैं इसे यहाँ रखा, कृपया एक नज़र रखना - pastebin.com/Uae6sE6s
its_me

8

यह वही है जिसके साथ मैं आया था और मैं अब तक इससे खुश हूं ...

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" 

टिप्पणियाँ:

  • हां, यह जटिल है ... लेकिन, यह सभी डुप्लिकेट को हटा देता है और फिर भी प्रत्येक टर्मिनल के भीतर कालक्रम को संरक्षित करता है!
  • मेरे HISTIGNOREसभी आदेशों को अनदेखा करता है जिनमें तर्क नहीं हैं। यह कुछ लोगों द्वारा वांछनीय नहीं हो सकता है और इसे छोड़ दिया जा सकता है।

1

इसके बजाय इसका उपयोग करें:

HISTCONTROL=ignoreboth

0

यह काम नहीं करता है, क्योंकि आप के बारे में भूल जाते हैं:

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

लेकिन ऐसा लगता history -nहै जब export HISTCONTROL=ignoreboth:erasedupsप्रभाव में है बस छोटी गाड़ी है।

चलिए प्रयोग करते हैं:

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

यहां हम युगों को मिटाते हैं, इतिहास को कस्टम फ़ाइल में बदलते हैं, इतिहास को साफ़ करते हैं। सभी कमांड पूर्ण होने के बाद हमारे पास खाली इतिहास फ़ाइल और वर्तमान इतिहास में एक कमांड है।

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

दूसरा टर्मिनल खोलें और उन छह कमांड को भी चलाएं। उसके बाद:

$ 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"

अब आपके वर्तमान इतिहास में दो कमांड हैं और इतिहास फ़ाइल में है:

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

पहले टर्मिनल पर वापस:

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

हुह ... कोई भी echoआदेश नहीं पढ़ा जाता है। फिर से दूसरे टर्मिनल पर जाएँ और:

$ echo "Z"
$ history -w

अब इतिहास फ़ाइल है:

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

पहले टर्मिनल पर फिर से जाएँ:

$ 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"कमांड को मर्ज कर दिया गया है history -n

एक और बग यह है क्योंकि कमांड की संख्या कमांड संख्या द्वारा इतिहास से पढ़ी जाती है, कमांड टाइम द्वारा नहीं, मुझे लगता है। मुझे उम्मीद है कि अन्य echoकमांड इतिहास में दिखाई देंगे


0

eradesups ट्रिम नहीं होते (जैसे कुछ भाषाओं में chomp) अग्रणी और अनुगामी स्थान। यह एक बग है। इसके अलावा मिटाए गए सभी पिछले प्रविष्टियों को हटा नहीं है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.