วิธีรวมคำสั่งใน PS1 ของ Bash โดยไม่หยุดการคำนวณความยาวบรรทัด


13

Tonin ชี้ให้เห็นข้อผิดพลาดในของฉันพรอมต์เริ่มต้น ตัวอย่างที่น้อยที่สุด:

  1. ตั้งค่า PS1:

    PS1='$(exit_code=$?; [[ $exit_code -eq 0 ]] || printf %s $(tput setaf 1) $exit_code $(tput sgr0) " ")$ '

    ณ จุดนี้พรอมต์จะมีลักษณะดังนี้:

    $ 
  2. ทริกเกอร์เอาท์พุทรหัสออกจากการทำงาน:

    false

    ตอนนี้พรอมต์ประกอบด้วยรหัสออกเป็นสีแดงที่จุดเริ่มต้นของบรรทัด:

    1 $ 
  3. กด-Ctrlr
  4. พิมพ์ "false" ตอนนี้พรอมต์มีเฉพาะการค้นหา:

    (reverse-i-search)`false': false
  5. Enterกด

ประวัติเทอร์มินัลที่ได้รับจะมีสิ่งต่อไปนี้:

1 $ch)`false': false

ผลลัพธ์ที่คาดหวัง:

1 $ false

นั่นคือดูเหมือนว่าเอาต์พุตการค้นหาประวัติจะถูกผสมกับพรอมต์และซ่อนคำสั่งจริงที่ถูกเรียกใช้

ฉันพยายามหลีกเลี่ยงปัญหานี้โดยใช้PROMPT_COMMAND :

set_exit_code() {
    exit_code=$?
    [[ $exit_code -eq 0 ]] || printf %s $(tput setaf 1) $exit_code $(tput sgr0) " "
}
set_bash_prompt() {
    PS1='$(set_exit_code)$ ' # Double quotes give the same result
}
PROMPT_COMMAND=set_bash_prompt

ดูเหมือนจะใช้งานไม่ได้ - บรรทัดนั้นเหมือนกับก่อนหน้าหลังการค้นหาและเรียกใช้

ฉันจะแก้ไขสิ่งนี้ได้อย่างไร


1
นี่น่าจะเป็นความต่อเนื่องของunix.stackexchange.com/a/71012
จัดการ

คำตอบ:


8

ผมพบคำตอบในaskubuntu.com @qeirha \[ \]กล่าวว่าคุณต้องบอกทุบตีว่าลำดับของตัวอักษรที่ไม่ควรจะนับความยาวพรอมต์และคุณทำอย่างนั้นโดยแนบไว้ใน จากตัวอย่างที่ให้มานี่คือวิธีแก้ปัญหาหนึ่ง:

red=$(tput setaf 1)

reset=$(tput sgr0)

[ "$PS1" = "\\s-\\v\\\$ " ] && PS1='$(exit_code=$?; [[ $exit_code -eq 0 ]] || printf %s \[$red\] $exit_code \[$reset\] " ")$ '

ไม่จำเป็นต้องไปที่ขอ Ubuntuสำหรับมัน เรามีคำตอบสำหรับคำถามนี้อยู่ที่นี่แล้วเช่นกัน
จัดการ

ขอบคุณสำหรับคำแนะนำ @manatwork! ฉันต้องการให้เครดิตที่เหมาะสมสำหรับคำอธิบายและให้การอ้างอิงเป็นมารยาท
Timothy Martin

การให้เครดิตไม่ใช่ปัญหา แต่ในขณะที่พูดถึงปัญหา: แบ็กสแลชที่ไม่ใช้ค่า Escape ใช้เพื่อลบล้างจาก Markdown ดังนั้นคุณธรรมดา \ [กลายเป็น [ในโพสต์ของคุณดังนั้นรหัสที่แสดงไม่ทำงานโดยการคัดลอกวางในเทอร์มินัล สามารถหลีกเลี่ยงได้โดยใช้รหัสแบบอินไลน์หรือมาร์กอัปบล็อกรหัส ( ฉันจะจัดรูปแบบโพสต์ของฉันโดยใช้ Markdown หรือ HTML ได้อย่างไร )
manatwork

1
D'โอ้! ฉันได้แก้ไขปัญหาเดียวกันสำหรับPS1รหัสอื่นแล้วเหตุใดฉันจึงไม่เห็นรหัสดังกล่าว
l0b0

1
PS1='$(exit_code=$?; [[ $exit_code -eq 0 ]] || printf %s \[$(tput setaf 1)\] $exit_code \[$(tput sgr0)\] " ")$ '

(ขออภัยไม่มีคำอธิบายที่นี่ดูวิธีปรับแต่ง PS1 ให้เหมาะสมหรือไม่หรือคำถามอื่น ๆ เกี่ยวกับปัญหาการคำนวณความยาวพร้อมท์และ\[.. \])


สำหรับคำถามที่สอง @ l0b0 ฉันจะเพิ่มโดยใช้ PS1 และ\[...\]ทำงานได้ดีตราบใดที่คุณสามารถใส่รหัสทั้งหมดที่คุณต้องการสร้างพรอมต์ของคุณในสตริงเดียว อย่างไรก็ตามหากคุณต้องการแยกรหัสของคุณออกเป็นฟังก์ชั่นขนาดเล็กคุณจะมาถึงจุดที่คุณไม่สามารถใส่วงเล็บเริ่มต้นและจุดสิ้นสุดลงในสตริง / ฟังก์ชันเดียวกันได้ และนั่นก็เป็นการตัดบรรทัด เว้นแต่คุณจะใช้PROMPT_COMMANDในการคำนวณของคุณอีกPS1ครั้งในแต่ละพรอมต์
Tonin

1

การขยายคำตอบ @manatwork แต่การรักษารหัสของคุณแยกการPS1คำนวณในฟังก์ชั่นที่แตกต่างกันคุณสามารถเขียนพรอมต์ของคุณด้วยวิธีต่อไปนี้:

set_exit_code() {
    exit_code=$?
    [[ $exit_code -eq 0 ]] || printf "\[$(tput setaf 1)\] $exit_code \[$(tput sgr0)\] "
}
set_bash_prompt() {
    PS1="$(set_exit_code)$ " # with double quotes!
}
PROMPT_COMMAND=set_bash_prompt

เครื่องหมายอัญประกาศคู่เป็นสิ่งจำเป็นทั้งเมื่อตั้งค่าPS1และเมื่อใช้printfในฟังก์ชัน


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