ZSH เทียบเท่ากับ $ PROMPT_COMMAND ของ BASH คืออะไร


24

BASH สนับสนุน$PROMPT_COMMANDตัวแปรสภาพแวดล้อมที่กำหนดคำสั่งที่จะดำเนินการก่อนที่จะมีการโต้ตอบระดับแรก ฉันกำลังมองหา ZSH ที่เท่ากัน

เอกสารบอกว่ามีฟังก์ชั่นที่precmdฉันสามารถนิยามได้ว่า; อย่างไรก็ตามฉันไม่ทราบวิธีการกำหนดจากตัวแปรสภาพแวดล้อม

ฉันได้พิจารณาผ่านตัวแปรสภาพแวดล้อมที่จะทำให้ ZSH อ่านไฟล์ที่มีคำจำกัดความของฟังก์ชั่นนั้น แต่ ZSH ดูเหมือนจะไม่สนับสนุนสิ่งต่าง ๆ : มันอ่านเฉพาะไฟล์ทั่วโลกแล้วต่อไฟล์ผู้ใช้ ฉันสามารถแทนที่พวกเขา แต่ฉันไม่สามารถเพิ่มพวกเขาโดยไม่ต้องแก้ไขไฟล์ซึ่งฉันไม่สามารถทำได้

ดังนั้นฉันจะกำหนด hook pre-prompt ใน ZSH ผ่านตัวแปรสภาพแวดล้อมเช่นเดียวกับที่ฉันใช้$PROMPT_COMMANDใน BASH ได้อย่างไร


ความจริงที่จะบอกฉันต้องการตะขอโพสต์แบบโต้ตอบคำสั่งดำเนินการ แต่เปลือกไม่ให้หนึ่งดังนั้นฉันต้องหันไปตะขอ pre-prompt - พวกเขาดูเหมือนจะใกล้เคียงที่สุดที่ฉันจะได้รับ
Shnatsel

1
หืมมมผมสงสัยว่าสิ่งที่แตกต่างระหว่างการโพสต์โต้ตอบคำสั่งการดำเนินการและpre-พรอมต์มี นอกเหนือจากความแตกต่างทางแนวคิดแล้วคุณสังเกตเห็นความแตกต่างจริง ๆ (เราจะexitexec;)
ละทิ้ง

@mpy มีความแตกต่างเมื่อใช้งานพื้นหลังเนื่องจากงานพื้นหลังไม่ขึ้นอยู่กับลำดับของพรอมต์
Shnatsel

1
ตกลงฉันได้รับจุดนั้น ดังนั้นวิธีการเกี่ยวกับสิ่งที่: start() { eval "$@"; echo post-command-code }แล้วใช้ zle- ผูกพันเพื่อรันบรรทัดคำสั่งด้วยstartprepended?
mpy

1
DEBUGกับดักที่จะหาที่ไหนดี แต่คุณยังคงมีปัญหาวิธีการที่จะกำหนดมัน ฉันได้ขยายคำตอบของฉันอีกครั้ง แต่ฉันปล่อยให้คุณเขียนคำตอบของคุณเองเกี่ยวกับการแก้ปัญหากับดัก DEBUG :)
mpy

คำตอบ:


24

วิธีที่ง่ายที่สุดในการเลียนแบบ bash $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/.zshenvไฟล์ rc 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

ฉันคิดว่ามาก ปัญหาคือ - ฉันจะกำหนด precmd hook ผ่านตัวแปรสภาพแวดล้อมได้อย่างไร มีกลไกในการเพิ่ม hooks หรือ code โดยไม่มีการแก้ไขไฟล์หรือไม่? หรือฉันจะทำอย่างน้อยโดยไม่ต้องเขียนไปทั่วโลกและผู้ใช้ทั่วโลก ".zprofile" และไฟล์ที่คล้ายกัน? เช่นฉันจะเพิ่ม. profile ของฉันเองที่จะไม่แทนที่โปรไฟล์ที่มีอยู่ได้หรือไม่
Shnatsel

1
ด้วยการใช้ตะขอ precmd ของคุณที่นี่จะแทนที่เบ็ด precmd ที่มีอยู่แล้วที่มีอยู่ทั้งหมด เอกสาร zsh พูดถึงฉันสามารถสร้างฟังก์ชั่นที่จะอยู่ร่วมกัน แต่ฉันไม่รู้ว่าจะทำอย่างไร
Shnatsel

1
(1) คุณหมายถึงอะไรฉันจะกำหนด precmd hook ผ่านตัวแปรสภาพแวดล้อมได้อย่างไร ตัวอย่างที่ฉันนำเสนอผลงาน IMHO เหมือนกลไกทุบตี (2) คุณสามารถเพิ่ม hook ผ่าน command-line แต่ก็ไม่ถาวร มีปัญหาอะไรกับการดัดแปลงของคุณ.zshrc? (3) ตัวอย่าง: foo() { echo foo }; bar() { echo bar }; precmd_functions=(foo bar)นี้ดำเนินการfoo()และbar() นอกเหนือprecmd()ไป
mpy

2
ตกลงนั่นเป็นสิ่งที่ชัดเจนมาก - ตัวอย่างเล็กน้อยสำหรับการทุบตีจะเป็นเช่นนั้นPROMPT_COMMAND="echo foo" bashใช่ไหม นี่คือความเป็นไปได้สำหรับการวางไข่ ZDOTDIR=/program/dir zshzsh: จากนั้น/program/dir/.zshrcจะมีแหล่งที่มาเมื่อคุณสามารถกำหนดตะขอ precmd () หากคุณต้องการให้ผู้ใช้เพิ่มเติมรวมถึงsource $HOME/.zshrcฯลฯ ในโปรแกรม zshrc ควรจะดูแลรักษาง่ายเนื่องจากไม่มีการแก้ไขไฟล์ภายนอกโปรแกรม dir
mpy

1
@Shnatsel: ฉันขยายคำตอบของฉัน บางทีคุณสามารถแก้ไขคำถามเพื่อรวมข้อมูลเพิ่มเติมจากความคิดเห็นของคุณ
mpy

5

ฐานะที่เป็นรัฐ @mypy, zsh ของ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
}

รันจากสคริปต์ shell init:

## ~/.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#Printing-a - พรอมต์

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.