BASH $ PROMPT_COMMAND'ın ZSH eşdeğeri nedir?


24

BASH, $PROMPT_COMMANDherhangi bir birinci düzey etkileşimli istemden önce yürütülecek komutu tanımlayan bir ortam değişkenini destekler . Bunun bir ZSH dengesini arıyorum.

Belgeler , bunu precmdbaşarmak için tanımlayabileceğim bir fonksiyon olduğunu söylüyor; ancak, bunu bir ortam değişkeninden nasıl tanımlayacağımı bilmiyorum.

ZSH'nin bu işlevin tanımını içeren bir dosyayı okumasını sağlayacak bir ortam değişkenini geçmeyi düşündüm, ancak ZSH bu tür şeyleri desteklemiyor gibi görünüyor : sadece global dosyaları ve sonra kullanıcı başına dosyaları okuyor. Bunları değiştirebilirim, ancak değiştiremediğim dosyaları değiştirmeden ekleyemiyorum.

Peki, BASH'de yaptığım gibi bir ortam değişkeni ile ZSH'de bir ön istem kancasını nasıl tanımlayabilirim $PROMPT_COMMAND?


Doğruyu söylemek gerekirse, bir post-interaktif-komut-yürütme kanca gerekir, ama ne kabuk bir ön sağlar kancaları istemek için başvurmak zorunda - onlar alabilirim kadar yakın gibi görünüyor.
Shnatsel

1
Hm, merak ediyorum, post-interaktif-komut yürütme ve ön istem arasındaki fark nedir. Kavramsal bir farkın dışında, aslında bir farkı nerede gözlemliyorsunuz? (Komutları exitexec;)
atlayalım

@mpy, bir arka plan işini çalıştırırken bir fark vardır, çünkü arka plan işleri bilgi istemi dizisinden bağımsızdır.
Shnatsel

1
Tamam, bu noktayı anladım. Peki, buna benzer bir şeye ne dersiniz: start() { eval "$@"; echo post-command-code }ve sonra komut satırını startbaşlayarak yürütmek için bir zle-bağlayıcı kullanın ?
mpy

1
DEBUGTuzak güzel bulmak, ama yine de nasıl tanımlamak sorun var. Cevabımı bir kez daha uzattım, ancak DEBUG tuzak çözümü ile ilgili kendi cevabınızı yazmayı size bırakıyorum. :)
mpy

Yanıtlar:


24

$PROMPT_COMMANDAklıma gelen bash'ı taklit etmenin en basit yaklaşımı precmd, daha önce de düşündüğünüz gibi kancayı kullanmaktır . Olarak tanımla

precmd() { eval "$PROMPT_COMMAND" }

ve böyle bir şey yapabilirsiniz:

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

Lütfen bu örnekteki tek tırnak işaretlerine dikkat edin, aksi takdirde $(date)çok erken genişletilir, yani tanımlamadan $PROMPT_COMMANDönce çağrıldığında değil, zaten tanımlanırken .


Mevcut tanımı korumak (ve değiştirmek istemiyorsanız), bu yaklaşımı kullanabilirsiniz:

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

Bununla prmptcmdfonksiyonlar mevcut precmd()fonksiyondan sonra yürütülür .


Son olarak, kullanıcı veya sistem dosyalarını değiştirmesi veya komutları etkileşimli olarak girmesi gereken bir program paketinde kullanılmaya uygun bir yol.

Bir bash oturumu oluşturmak için bir örnek olabilir

PROMPT_COMMAND="echo foo" bash

Zsh yumurtlamak için kullanabilirsiniz

ZDOTDIR=/program/dir zsh

kaynaklanmasına neden olur /program/dir/.zshrc. Bu dosyada precmd()kanca yukarıda açıklandığı gibi tanımlanabilir. Kullanıcının ayarları isterseniz ek olarak dahil source $HOME/.zshrcçok programın .zshrc dosyanızda vb. Program dizini dışındaki hiçbir dosya değiştirilmediğinden bu kurulum korunabilir.


Son bir ek olarak, burada yeni kullanıcının nasıl hoş karşılanacağına dair bir kavram kanıtı. /program/dir/.zshenvRc config dosyanızda aşağıdaki kodu kullanın :

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

Ben de öyle düşündüm. Sorun - precmd kancasını bir ortam değişkeni ile nasıl tanımlayabilirim? Dosyaları değiştirmeden kanca veya kod eklemek için bir mekanizma var mı? Ya da en azından global ve kullanıcı-global ".zprofile" ve benzeri dosyalara yazmadan nasıl yapabilirim? Gibi, mevcut olanların yerine kendi .zprofile ekleyebilir miyim?
Shnatsel

1
Ayrıca burada precmd kanca kullanımınız, mevcut tüm precmd kancaları değiştirir; zsh docs bir arada var olacak fonksiyonları bir dizi yapabilirsiniz bahsetmek ama bunu nasıl yapacağım hakkında hiçbir fikrim yok.
Shnatsel

1
(1) Bir ortam değişkeni aracılığıyla precmd kancasını nasıl tanımlayabilirim? Sunduğum örnek IMHO gibi bash mekanizması gibi çalışıyor. (2) Kancayı komut satırı üzerinden ekleyebilirsiniz, ancak daha sonra kalıcı değildir. Modifikasyonunuzdaki sorun nedir .zshrc? (3) Bir örnek: foo() { echo foo }; bar() { echo bar }; precmd_functions=(foo bar)Bu yürütülür foo()ve bar() ek olarak precmd().
mpy

2
Tamam, bu çok açıklığa kavuştu - o zaman bash için minimal bir örnek olurdu PROMPT_COMMAND="echo foo" bash, değil mi? Zsh yumurtlama için bu bir olasılık var: ZDOTDIR=/program/dir zsh. Daha sonra /program/dir/.zshrc, precmd () kancasını tanımlayabileceğiniz başlangıçta kaynaklanır. Kullanıcının ek source $HOME/.zshrcolarak programın zshrc içine vb. Programın dışındaki hiçbir dosya değiştirilmediğinden, bu işlemin bakımı kolay olmalıdır.
mpy

1
@Shnatsel: Cevabımı uzattım. Belki de yorumunuzdaki ek bilgileri içerecek şekilde sorunuzu düzenleyebilirsiniz.
mpy

5

@ Mypy'nin belirttiği gibi, Zsh'ın Bash'lara precmdbenzer şekilde çalışması PROMPT_COMMAND.

Bash veya Zsh için çalışan ve kullanmayan bir örnek 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
}

Kabuk başlangıç ​​komut dosyalarından çalıştır:

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

ve:

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

Buradaki istemler sadece örnektir. Kesinlikle çok daha zor şeyler yapabilir.

Bilgi istemi işlevlerini ayarlama ile ilgili ayrıntılar için bkz. Http://zsh.sourceforge.net/Doc/Release/Functions.html#index-precmd ve http://www.gnu.org/software/bash/manual/bashref.html # İstemi Yazdırma .

Hızlı genişletmelerin ayrıntıları için bkz. Http://zsh.sourceforge.net/Doc/Release/Prompt-Expansion.html ve http://www.gnu.org/software/bash/manual/bashref.html#Printing-a -İstemi .

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.