यह बताएं कि क्या PROMPT_COMMAND में अंतिम कमांड खाली थी


12

PROMPT_COMMAND के अंदर से बैश में, यह बताने का कोई तरीका है कि क्या उपयोगकर्ता केवल 'रिटर्न' हिट करता है और उसने कमांड दर्ज नहीं की है?

जवाबों:


7

जांचें कि क्या इतिहास संख्या बढ़ाई गई थी। रद्द किया गया संकेत या संकेत जहां उपयोगकर्ता ने अभी-अभी दबाया है Enter, इतिहास संख्या में वृद्धि नहीं करेगा।

इतिहास संख्या चर में उपलब्ध है HISTCMD, लेकिन इसमें उपलब्ध नहीं है PROMPT_COMMAND(क्योंकि आप जो चाहते हैं, वास्तव में पिछली कमांड की इतिहास संख्या है, जो कमांड PROMPT_COMMANDखुद को निष्पादित करता है उसका कोई इतिहास संख्या नहीं है)। के आउटपुट से आप नंबर प्राप्त कर सकते हैं fc

prompt_command () {
  HISTCMD_previous=$(fc -l -1); HISTCMD_previous=${HISTCMD_previous%%$'[\t ]'*}
  if [[ -z $HISTCMD_before_last ]]; then
    # initial prompt
  elif [[ $HISTCMD_before_last = "$HISTCMD_previous" ]]; then
    # cancelled prompt
  else
    # a command was run
  fi
  HISTCMD_before_last=$HISTCMD_previous
}
PROMPT_COMMAND='prompt_command'

ध्यान दें कि यदि आपने इतिहास ( HISTCONTROL=ignoredupsया HISTCONTROL=erasedups) में डुप्लिकेट के स्क्वाशिंग को चालू कर दिया है , तो यह क्रमिक रूप से दो समान आदेशों को क्रमिक रूप से चलाने के बाद एक खाली कमांड को रिपोर्ट करेगा।


धन्यवाद, गिल्स। मुझे यहाँ कुछ याद आ रहा है। यह कभी नहीं लगता है, क्योंकि शाब्दिक फ़ंक्शन की पहली पंक्ति पर 'इको हेलो' डालने से काम नहीं चलता, हालांकि PROMPT_COMMAND = 'इको हेलो' करता है। मुझे लगा कि यह HISTCMD_prepret बनाम HISTCMD_PREVIOUS मुद्दा हो सकता है, लेकिन कोई पासा नहीं। मैं मज़ाक करता रहूंगा, लेकिन मैं टिप्पणी कर रहा हूं क्योंकि आपका बैश फू स्पष्ट रूप से मेरा है।
उपयोगकर्ता

@user मैंने अधिक टाइपोस तय किया, विशेष रूप से ${HISTCMD_previous%%$'[\t ]'*}बिट गायब था $'…'और `, टैब या स्पेस के बजाय t` या स्पेस के बाद ट्रंकटिंग समाप्त हो गया , लेकिन बैश एक टैब प्रिंट करता है।
गिल्स एसओ- बुराई को रोकें '

1
यह समाधान इस धारणा पर आधारित है कि डुप्लिकेट को इतिहास में सहेजा जाता है (जो मेरे लिए बंद है)। इसलिए यह समाधान दोहराए गए आदेशों की अपेक्षा के अनुरूप काम नहीं करता है, जबकि डुप्लिकेट इतिहास में सहेजे नहीं जाते हैं।
schlimmchen

4

वर्कअराउंड है, लेकिन इसकी कुछ आवश्यकताएं हैं:

आपको $HISTCONTROLसभी आदेश, डुप्लिकेट और रिक्त स्थान को बचाने के लिए सेट करने की आवश्यकता है । तो सेट करें:

HISTCONTROL=

अब एक फंक्शन को इस प्रकार परिभाषित करें $PROMPT_COMMAND:

isnewline () {
  # read the last history number
  prompt_command__isnewline__last="$prompt_command__isnewline__curr"
  # get the current history number
  prompt_command__isnewline__curr="$(history 1 | grep -oP '^\ +\K[0-9]+')"
  [ "$prompt_command__isnewline__curr" = "$prompt_command__isnewline__last" ] && \
    echo "User hit return"
}

अब, $PROMPT_COMMANDचर सेट करें :

PROMPT_COMMAND="isnewline"

आउटपुट देखें:

user@host:~$ true
user@host:~$ <return>
User hit return
user@host:~$ <space><return>
user@host:~$ 

मुझे समझ नहीं आ रहा है कि आप यहाँ एक अस्थायी फ़ाइल का उपयोग क्यों कर रहे हैं। चर lastको isnewlineअगले के एक आह्वान से संरक्षित किया जाता है (केवल कम जेनेरिक नाम चुना जाता है जैसे prompt_command__isnewline__lastझड़पों से बचना)।
गिल्स एसओ-

@Gilles आप रहे हों तो सही, मैं इसे बदल गया है, आपके सुझाव के लिए धन्यवाद
अराजकता

धन्यवाद, अराजकता। मैंने निम्नलिखित के लिए एक ही विचार का उपयोग किया, जो कि पार्स करना थोड़ा आसान है। HISTCONTROL="" function last_was_blank { local last_command="$(history 1)" if [[ "$last_was_blank_PREVIOUS_LINE" = "$last_command" ]] ; then echo "true" else echo "false" fi export last_was_blank_PREVIOUS_LINE="$last_command" } PROMPT_COMMAND=last_was_blank
उपयोगकर्ता

1

मुझे ऐसा करने का तरीका नहीं पता, प्रति से । लेकिन आप एक ही प्रभाव का उपयोग करके प्राप्त कर सकते हैं

trap some_command_or_function डीबग

यह some_command_or_functionकिसी भी समय आपको कमांड चलाने के लिए बुलाया जाएगा। मुश्किल बात यह है, अगर आप सिर्फ हिट करते हैं तो इसे कॉल नहीं किया जाएगा Enter- जब तक कि आपके पास एक PROMPT_COMMAND परिभाषित न हो, जिस स्थिति में हिट Enterकरना PROMPT_COMMAND, जो बदले में, ट्रैप को ट्रिगर करता है।

परिणाम प्राप्त करने का सबसे सरल तरीका शायद यह है कि आप PROMPT_COMMAND का उपयोग करने के बजाय डिबग ट्रैप फ़ंक्शन को परिभाषित करें। लेकिन मैं नहीं बता सकता, क्योंकि मैं नहीं जानता कि आपको क्या परिणाम चाहिए। यदि आप चाहते हैं कि जब आप बस हिट करें Enter, और जब आप एक कमांड टाइप करें, तब कुछ अलग / अतिरिक्त हो, तब (AFAIK) आपको डीबग जाल और PROMPT_COMMAND का उपयोग करने की आवश्यकता है। देखें इस सवाल का जवाब और  इस एक एक तरह से दो प्रणालियों का एक साथ अच्छी तरह से खेलने के लिए बनाने के लिए।


0

(यह स्वीकृत उत्तर के लिए एक टिप्पणी होती अगर मुझे टिप्पणी जोड़ने की अनुमति दी गई होती ...) @ शालिमन, आप HISTTIMEFORMATकुछ पसंद कर सकते हैं HISTTIMEFORMAT='%F %T 'और फिर सहेज सकते हैं और तुलना कर सकते हैं history 1। ऐसा इसलिए है क्योंकि हर बार कम से कम (संभवतः बार-बार) अंतिम समय में मिटाए जाने के साथ मिटा दिया जाता है --- और HISSTIMEFORMATउचित रूप से सेट के साथ , history 1टाइमस्टैम्प (इसके विपरीत fc) प्रदर्शित करेगा , और इस तरह दोहराया कमांड के बीच भी भिन्न होता है।

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