BASH के $ PROMPT_COMMAND के बराबर ZSH क्या है?


24

BASH एक $PROMPT_COMMANDपर्यावरण चर का समर्थन करता है जो किसी भी प्रथम-स्तरीय इंटरैक्टिव प्रॉम्प्ट से पहले निष्पादित होने वाली एक कमांड को परिभाषित करता है। मुझे लगता है कि एक ZSH संतुलन के लिए देख रहा हूँ।

प्रलेखन कहता है कि एक ऐसा कार्य है जिसे precmdमैं इसे प्राप्त करने के लिए परिभाषित कर सकता हूं; हालाँकि, मुझे नहीं पता कि इसे पर्यावरण चर से कैसे परिभाषित किया जाए।

मैंने एक पर्यावरण चर को पारित करने पर विचार किया है जो ZSH को उस फ़ंक्शन की परिभाषा वाली फ़ाइल को पढ़ने देगा, लेकिन ZSH ऐसी चीजों का समर्थन नहीं करता है : यह केवल वैश्विक फ़ाइलों और फिर प्रति-उपयोगकर्ता फ़ाइलों को पढ़ता है। मैं उन्हें बदल सकता हूं लेकिन मैं उन फाइलों को संशोधित किए बिना उन्हें नहीं जोड़ सकता, जो मैं नहीं कर सकता।

तो मैं कैसे एक पर्यावरण चर के माध्यम से ZSH में एक पूर्व-शीघ्र हुक को परिभाषित करता हूं, जैसे मैं $PROMPT_COMMANDBASH में उपयोग कर रहा हूं ?


सच कहा जाए, तो मुझे पोस्ट-इंटरैक्टिव-कमांड-एक्ज़ीक्यूशन हुक की ज़रूरत है, लेकिन न तो शेल एक प्रदान करता है, इसलिए मुझे प्री-प्रॉम्प्ट हुक का सहारा लेना पड़ता है - वे मुझे जितना संभव हो उतना करीब लगते हैं।
श्नात्सेल

1
हम्म, मैं सोच रहा हूं कि पोस्ट-इंटरएक्टिव-कमांड-एक्जीक्यूशन और प्री-प्रांप्ट में क्या अंतर है। एक वैचारिक अंतर के अलावा, आप वास्तव में एक अंतर कहां देखते हैं। (चलो आज्ञाओं को छोड़ दें exitऔर exec, ठीक है ;))
mpy

@ बैकग्राउंड जॉब चलाते समय अंतर होता है, क्योंकि बैकग्राउंड जॉब्स प्रॉम्प्ट सीक्वेंस से स्वतंत्र होते हैं।
शनात्सेल

1
ठीक है, मुझे वह बात मिल गई। तो, कैसे के बारे में कुछ इस तरह: start() { eval "$@"; echo post-command-code }और फिर पूर्व निर्धारित के साथ कमांड लाइन को निष्पादित करने के लिए एक zle- बाध्यकारी का उपयोग करें start?
मैपी

1
DEBUGजाल एक अच्छा खोज है, लेकिन आप अभी भी समस्या है कि यह कैसे परिभाषित करने के लिए किया है। मैंने अपना उत्तर एक बार और बढ़ा दिया है, लेकिन मैं आपको DEBUG ट्रैप समाधान के बारे में अपना उत्तर लिखने के लिए इसे छोड़ देता हूं। :)
मपी

जवाबों:


24

बाश का अनुकरण करने का सबसे सरल तरीका $PROMPT_COMMANDजो मेरे दिमाग में आता है precmd, वह हुक का उपयोग करना है , जैसा कि आप पहले ही समझ चुके हैं। इसे परिभाषित करें

precmd() { eval "$PROMPT_COMMAND" }

और आप ऐसा कुछ कर सकते हैं:

$ PROMPT_COMMAND='echo Hello, it is now $(date)'
Hello, it is now Mon, Mar 31, 2014 7:08:00 PM
$ whoami      
user
Hello, it is now Mon, Mar 31, 2014 7:08:21 PM     
$

कृपया उस उदाहरण में एकल उद्धरणों पर ध्यान दें, अन्यथा $(date)बहुत जल्दी विस्तारित हो जाएगा, अर्थात पहले से ही परिभाषित करते समय $PROMPT_COMMANDऔर जब संकेत के पहले नहीं बुलाया जाएगा।


यदि आप मौजूदा परिभाषा को संरक्षित (और बदलना नहीं चाहते) चाहते हैं, तो आप उस दृष्टिकोण का उपयोग कर सकते हैं:

$ prmptcmd() { eval "$PROMPT_COMMAND" }
$ precmd_functions=(prmptcmd)

इसके साथ prmptcmdमौजूदा precmd()फ़ंक्शन के बाद फ़ंक्शन निष्पादित किए जाते हैं।


अंत में, यहां एक तरीका है जो प्रोग्राम पैकेज में उपयोग के लिए उपयुक्त है, जिसे न तो उपयोगकर्ता या सिस्टम फ़ाइलों को संशोधित करना चाहिए और न ही कमांड्स को इंटरएक्टिव दर्ज कर सकते हैं।

बैश सत्र शुरू करने का एक उदाहरण हो सकता है

PROMPT_COMMAND="echo foo" bash

Zsh को स्पॉन करने के लिए आप उपयोग कर सकते हैं

ZDOTDIR=/program/dir zsh

जिसके कारण /program/dir/.zshrcखटास आ जाती है। इस फ़ाइल में precmd()हुक को ऊपर बताए अनुसार परिभाषित किया जा सकता है। आप उपयोगकर्ता की सेटिंग चाहते हैं इसके अलावा में शामिल हैं source $HOME/.zshrc, भी कार्यक्रम के .zshrc में आदि। यह सेटअप बनाए रखने योग्य है, क्योंकि प्रोग्राम डायरेक्टरी के बाहर की कोई फाइल संशोधित नहीं है।


अंतिम जोड़ के रूप में, यहां अवधारणा का एक प्रमाण है कि कैसे नवागंतुक का स्वागत किया जाए। अपनी /program/dir/.zshenvrc config फाइल में निम्न कोड का उपयोग करें :

echo define precmd, traps, etc.

autoload -Uz zsh-newuser-install

if [[ ! -e "$HOME/.zshrc" ]]; then
  zsh-newuser-install -f
  mv $ZDOTDIR/.zshrc $HOME/.zshrc
else
  builtin source $HOME/.zshrc
fi

इतना मैं समझ गया। समस्या यह है - मैं एक पर्यावरण चर के माध्यम से प्रेडम हुक को कैसे परिभाषित करूं? क्या फाइलों को संशोधित किए बिना हुक या कोड जोड़ने का एक तंत्र है? या मैं इसे कम से कम कैसे वैश्विक और उपयोगकर्ता-वैश्विक ".zprofile" और इसी तरह की फ़ाइलों के बिना लिखूं? जैसे, क्या मैं अपना स्वयं का .zprofile जोड़ सकता हूं जो मौजूदा वाले को प्रतिस्थापित नहीं करेगा?
शनात्सेल

1
इसके अलावा यहां आपके द्वारा दिए गए प्रॉमम हुक का उपयोग किसी भी मौजूदा मौजूदा प्राइमड हुक को बदल देगा; zsh डॉक्स का उल्लेख है कि मैं ऐसे कार्यों की एक सरणी बना सकता हूं जो सह-अस्तित्व में होंगे लेकिन मुझे नहीं पता कि यह कैसे करना है।
शनात्सेल

1
(१) पर्यावरण चर के माध्यम से प्रेडम हुक को मैं कैसे परिभाषित करूँ? मैंने पेश किया उदाहरण bash तंत्र की तरह IMHO काम करता है। (2) आप हुक को कमांड-लाइन के माध्यम से जोड़ सकते हैं, लेकिन तब यह स्थायी नहीं है। आपके संशोधन के साथ समस्या क्या है .zshrc? (३) एक उदाहरण: foo() { echo foo }; bar() { echo bar }; precmd_functions=(foo bar)यह क्रियान्वित foo()और bar() इसके अतिरिक्त है precmd()
मैपी

2
ठीक है, जो बहुत कुछ स्पष्ट करता है - बैश के लिए एक न्यूनतम उदाहरण तब होगा PROMPT_COMMAND="echo foo" bash, है ना? क्या यह स्पश ज़िंग के लिए एक संभावना है ZDOTDIR=/program/dir zsh:। फिर /program/dir/.zshrcशुरू पर खट्टा होता है जहां आप प्रीमेड () हुक को परिभाषित कर सकते हैं। यदि आप उपयोगकर्ता के अलावा source $HOME/.zshrcकार्यक्रम के zshrc में शामिल आदि चाहते हैं। इसे बनाए रखना आसान होना चाहिए, क्योंकि कार्यक्रम के बाहर कोई भी फाइल संशोधित नहीं है।
21

1
@ शांतासेल: मैंने अपना उत्तर बढ़ाया। शायद आप अपनी टिप्पणी से अतिरिक्त जानकारी को शामिल करने के लिए अपने प्रश्न को संपादित कर सकते हैं।
मपी

5

@ मम्पी बताती है, ज़श बश के precmdसमान काम करता है PROMPT_COMMAND

यहाँ एक उदाहरण है जो Bash या Zsh के लिए काम करता है और इसका उपयोग नहीं करता है eval:

## ~/myprompt.sh

# 'ZSH_VERSION' only defined in Zsh
# 'precmd' is a special function name known to Zsh

[ ${ZSH_VERSION} ] && precmd() { myprompt; }

# 'BASH_VERSION' only defined in Bash
# 'PROMPT_COMMAND' is a special environment variable name known to Bash

[ ${BASH_VERSION} ] && PROMPT_COMMAND=myprompt

# function called every time shell is about to draw prompt
myprompt() {
  if [ ${ZSH_VERSION} ]; then
    # Zsh prompt expansion syntax
    PS1='%{%F{red}%}%n%{%f%}@%{%F{red}%}%m %{%F{cyan}%}%~ %{%F{white}%}%# %{%f%}'
  elif [ ${BASH_VERSION} ]; then
    # Bash prompt expansion syntax
    PS1='\[\e[31m\]\u\[\e[0m\]@\[\e[31m\]\h \[\e[36m\]\w \[\e[37m\]\$ \[\e[0m\]'
  fi
}

शेल इनिट स्क्रिप्ट से चलाएँ:

## ~/.bashrc
. ~/myprompt.sh

तथा:

## ~/.zshrc
. ~/myprompt.sh

यहाँ संकेत केवल उदाहरण हैं। एक निश्चित रूप से बहुत मुश्किल सामान कर सकते हैं।

शीघ्र कार्य निर्धारित करने के विवरण के लिए, देखें: http://zsh.sourceforge.net/Doc/Release/Functions.html#index-precmd और http://www.gnu.org/software/bash/manual/bashref.html # प्रिंटिंग-ए-प्रॉम्प्ट

शीघ्र विस्तार के विवरण के लिए, http://zsh.sourceforge.net/Doc/Release/Prompt-Expansion.html और http://www.gnu.org/software/bash/manual/bashref.html#Printinga देखें । -पढ़ना

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