เทอร์มินัลพรอมต์ไม่ถูกต้อง


171

ฉันมีปัญหาเมื่อฉันพิมพ์คำสั่งที่ยาวมากใน bash เทอร์มินัลจะไม่แสดงสิ่งที่ฉันพิมพ์อย่างถูกต้อง ฉันคาดหวังว่าถ้าฉันมีคำสั่งดังต่อไปนี้:

username@someserver ~/somepath $ ssh -i /path/to/private/key
myusername@something.someserver.com

คำสั่งควรแสดงผลสองบรรทัด แต่มันมักจะพันไปรอบ ๆ และเริ่มเขียนที่ส่วนบนของพรอมต์ของฉันค่อนข้างเป็นดังนี้:

myreallylongusername@something.somelongserver.comh -i /path/to/private/key

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

ความสนุกสนานเพิ่มเติมเกิดขึ้นเมื่อฉันUpไปที่คำสั่งก่อนหน้า ฉันได้ลองใช้ทั้ง gnome-terminal และ terminator และใน i3 และ Cinnamon มีคนแนะนำว่านั่นคือพรอมต์ของฉันดังนั้นนี่คือ:

\[\033[01;32m\]\u:\[\033[01;34m\] \W\033[01;34m \$\[\033[00m\]

Ctrll, resetและclearทุกคนทำในสิ่งที่พวกเขาพูด แต่เมื่อฉันพิมพ์คำสั่งกลับมาหรือUpสิ่งเดียวกันเกิดขึ้น

ฉันตรวจสอบและcheckwinsizeเปิดใช้งานในทุบตี สิ่งนี้เกิดขึ้นใน 80x24 และขนาดหน้าต่างอื่น ๆ

นี่เป็นเพียงสิ่งที่ฉันเรียนรู้ที่จะอยู่ด้วยหรือไม่? มีชิ้นส่วนของเวทมนตร์ที่ฉันควรรู้หรือไม่? ฉันได้ตัดสินเพียงแค่ใช้พรอมต์สั้น ๆ แต่ก็ไม่สามารถแก้ไขปัญหาได้


1
ดังนั้นการใช้คำสั่งenv -i bash --norcแก้ไขมัน $ COLUMNS และ $ LINES ตรงกัน นั่นหมายความว่ามีบางสิ่งที่ตลกกับ. bashrc ของฉันหรือไม่
Muricula

ดังนั้นฉันจึงแสดงความคิดเห็น. bashrc ของฉันและปิดกั้นพรอมต์ของฉันในฐานะส่วนที่มีปัญหาโดยเฉพาะไวยากรณ์ของสีที่เกี่ยวข้อง เกิดอะไรขึ้นกับ PS1 ด้านบน
Muricula

1
\[\033[01;32m\]\u: \[\033[01;34m\]\W \[\033[01;34m\] \$ \[\033[0m\]ดูเหมือนว่าจะหลีกเลี่ยงความแปลกประหลาดในพฤติกรรม - แต่ไม่ทราบว่ามันเคารพพรอมต์ดั้งเดิมของคุณอย่างสมบูรณ์ ...

1
ตามคำตอบนี้ใน serverfaultให้ใช้tput smam
Samveen

คำตอบ:


189

ลำดับที่ไม่สามารถพิมพ์ควรจะล้อมรอบใน\[\]และ มองไปที่PS1ของคุณมันมีลำดับที่ไม่มีการปิดบังหลังจาก\Wนั้น แต่รายการที่สองคือซ้ำซ้อนเช่นเดียวกับมันซ้ำคำสั่งก่อนหน้านี้"1; 34"

\[\033[01;32m\]\u:\[\033[01;34m\] \W\033[01;34m \$\[\033[00m\]
                  |_____________|               |_|
                         |                       |
                         +--- Let this apply to this as well.

เช่นนี้ควรมีการกำหนดสี:

\[\033[1;32m\]\u:\[\033[1;34m\] \W \$\[\033[0m\]
                               |_____|
                                  |
                                  +---- Bold blue.

การรักษา"ต้นฉบับ"นี้ควรทำงาน:

\[\033[1;32m\]\u:\[\033[1;34m\] \W\[\033[1;34m\] \$\[\033[0m\]
                                  |_|         |_|
                                   |           |
                                   +-----------+-- Enclose in \[ \]

แก้ไข:

สาเหตุของพฤติกรรมเป็นเพราะbashเชื่อว่าพรอมต์นั้นยาวกว่าจริง ๆ แล้วมันคือ ตัวอย่างง่ายๆหากใช้:

PS1="\033[0;34m$"
       1 2345678

เชื่อว่าพรอมต์เป็น 8 อักขระและไม่ใช่ 1 เช่นถ้าหน้าต่างเทอร์มินัลคือ 20 คอลัมน์หลังจากพิมพ์ 12 อักขระเชื่อว่าเป็น 20 และล้อมรอบ และนี่ก็เป็นที่เห็นได้ชัดถ้าใครแล้วพยายามที่จะทำ Backspace Ctrl+uหรือ มันหยุดที่คอลัมน์ 9

อย่างไรก็ตามมันยังไม่ได้เริ่มต้นขึ้นบรรทัดใหม่ยกเว้นว่ามีหนึ่งอยู่ในคอลัมน์สุดท้ายดังนั้นผลลัพธ์บรรทัดแรกจะถูกเขียนทับ

หากมีคนพิมพ์บรรทัดควรตัดบรรทัดถัดไปหลังจาก 32 ตัวอักษร


หากคุณ - หรือใครก็ตาม - มีคำอธิบายเกี่ยวกับสิ่งที่อยู่ในลำดับเดิมที่ทำให้สายการทำซ้ำตัวเองฉันจะสนใจที่จะรู้ว่า +1 ด้วยวิธีที่คุณแสดงให้เห็นด้วยสายตา

1
@ illuminÉ: ยังไม่ได้ดูที่แหล่งที่มา แต่เพิ่มการปรับปรุงด้วยหมายเหตุเกี่ยวกับพฤติกรรมจากการสังเกต
Runium

ในกรณีที่คุณประสบปัญหาคุณสามารถใช้เว็บไซต์นี้เพื่อสร้างเว็บไซต์ใหม่ - bashrcgenerator.com
divinedragon

นี่เป็นเรื่องที่น่าอัศจรรย์ขอบคุณ @Runium - คุณจะแบ่งปันความรู้สึกอย่างไรให้รู้ ฉันชอบที่จะหาเอกสารเกี่ยวกับเรื่องนี้
nycynik

2
@nycynik: การสังเกต ฉันเดาว่าเอกสารที่ใกล้เคียงที่สุดในที่นี้คือซอร์สโค้ด ...
Runium

83

ส่วนใหญ่แล้วจะเกี่ยวกับขนาดของหน้าต่างที่เทอร์มินัลสันนิษฐานว่าไม่เหมือนกับขนาดหน้าต่างจริงของคุณ หากคุณกำลังใช้ bash คุณสามารถลองสิ่งนี้

$ shopt checkwinsize

หากคุณไม่ได้รับ

checkwinsize    on

จากนั้นเปิดใช้งานด้วย

$ shopt -s checkwinsize

จากนั้นให้ลองเรียกใช้คำสั่งอื่น (เช่นls) หรือปรับขนาดหน้าต่างหนึ่งครั้งด้านบนใช้ได้สำหรับฉันทุกครั้ง

สำหรับระบบ Redhat โดยเฉพาะอย่างยิ่งปัญหามักจะเกิดจาก misconfiguring จะไม่เรียก~/.bashrc /etc/bashrcปกติโหลดทุบตี~/.bashrcซึ่งคาดว่าจะเรียกซึ่งโดยค่าเริ่มต้นมี/etc/bashrcshopt -s checkwinsize


พบปัญหาเดียวกันกับ OS X ถ้าคุณเรียกว่า "เข้าสู่ระบบ" เพื่อเริ่มต้นเทอร์มินัลมันจะเริ่มต้นทุบตีในแบบที่อ่าน / etc / bashrc แต่ถ้าคุณโทรหาทุบตีโดยตรง ~ / .bashrc จะไม่ สิ่งที่มาโดยค่าเริ่มต้นเพื่อให้คุณได้รับผลกระทบการตัดแปลก ขอบคุณ!
rogerdpack

สิ่งนี้ใช้ได้สำหรับฉันเช่นกัน สีไม่ได้อยู่ในเซิร์ฟเวอร์นี้โดยเฉพาะการโทรถูกต้อง/etc/bashrcทุกอย่างดีไป ... ปรากฎว่านี่เป็นสาเหตุของปัญหาการตัดคำ
dhaupin

ดูเพิ่มเติมที่unix.stackexchange.com/a/61608/2221
astrojuanlu

ดูเหมือนว่าเป็นทางออกที่ดี แต่มันไม่ทำงานในเซสชั่น ssh ของฉัน ไม่แน่ใจว่าทำไม ฉันได้รันคำสั่งshopt -s checkwinsizeในเซสชัน ssh แต่การห่อยังคงมีอยู่
Qiang Xu

นี่เป็นปัญหาของฉันอย่างแม่นยำ - ผู้ใช้. bashrc ไม่ได้โทร / etc / bashrc และทำสิ่งสกปรก
Sobrique

9

ตามที่ระบุไว้ในคำตอบอื่น ๆ ลำดับที่ไม่สามารถพิมพ์เช่นควรห่อหุ้มด้วย\e[0;30m\[...\]

นอกจากนี้ (และสิ่งที่ฉันไม่เห็นกล่าวถึงยัง) คือดูเหมือนว่า\r\nควรจะออกไปข้างนอกของ\[...\]ถ้าคุณมีพรอมต์หลายสาย ในที่สุดฉันก็ต้องลองใช้และลองผิดลองถูก


8

ฉันเคยอ่านที่ไหนสักแห่ง (ไม่รู้ว่าจะอยู่ที่ไหนอีกแล้ว) ที่ใช้\001และ\002แทนที่จะเป็น\[และ\]สามารถแก้ปัญหานี้ได้ มันทำเพื่อฉัน

โดยวิธีการกำหนด PS1 ไม่จำเป็นต้องดูน่าเกลียด

green="\001$(tput setaf 2)\002"
blue="\001$(tput setaf 4)\002"
dim="\001$(tput dim)\002"
reset="\001$(tput sgr0)\002"

PS1="$dim[\t] " # [hh:mm:ss]
PS1+="$green\u@\h" # user@host
PS1+="$blue\w\$$reset " # workingdir$

export PS1
unset green blue dim reset

2
PS1 ของฉันเรียกคำสั่งที่ลำดับ escape ของ printf ทำให้เกิดปัญหาของ OP เฉพาะโซลูชันนี้แก้ไขปัญหาสำหรับฉัน
RickMeasham

6

ดูเหมือนว่ามีปัญหากับการตั้งค่าตัวแปรCOLUMNS& LINESสภาพแวดล้อมของคุณ เมื่อคุณปรับขนาดหน้าต่างโดยทั่วไปแล้วพวกมันจะถูกตั้งค่าโดยอัตโนมัติด้วย gnome-terminal (ฉันเชื่อว่า) คุณสามารถบังคับให้พวกมันตั้งค่าเองresizeได้

ตัวอย่าง

ถ้าฉันปรับขนาด gnome-terminal เป็น 79x17 ตัวแปรของฉันจะปรากฏขึ้นเช่น:

$ echo $COLUMNS; echo $LINES
79
17

ฉันสามารถบังคับได้เช่น:

$ resize
COLUMNS=79;
LINES=17;
export COLUMNS LINES;

1
น่าสนใจ แต่ไม่ได้ช่วยอะไร
Muricula

1
แก้ไขปัญหาของฉันแล้วว่าไม่ได้ตัดเส้นอย่างถูกต้องหลังจากฉันเรียกใช้คำสั่ง "หน้าจอ" ขอบคุณ !!
nukeguy

5

เพื่อป้องกันการพันคุณสามารถเพิ่มจำนวนคอลัมน์ที่ใช้เช่น

stty columns 120

1
ไม่ใช่ความคิดที่ดีมากมันทำให้สับสนอย่างไร้ความปราณี
Blauhirn

3

นอกจากนี้ปัญหาเดียวกันอาจเกิดจากการใช้สัญลักษณ์ unicode แบบกว้าง (เช่นจากhttps://stackoverflow.com/a/34812608/1657819 ) นี่คือตัวอย่างข้อมูลที่ทำให้เกิดปัญหา (โปรดระวัง$Greenและ$Redหลีกเลี่ยงการใช้สตริงสีอย่างเหมาะสม):

FancyX='\342\234\227'
Checkmark='\342\234\223'


# Add a bright white exit status for the last command
PS1="$White\$? "
# If it was successful, print a green check mark. Otherwise, print
# a red X.
if [[ $Last_Command == 0 ]]; then
    PS1+="$Green$Checkmark "
else
    PS1+="$Red$FancyX "
fi

Bash ไม่สามารถคำนวณความยาวได้อย่างถูกต้องดังนั้นวิธีที่ง่ายที่สุดคือการหลีกเลี่ยง 2 ในสามส่วนของสัญลักษณ์กว้างเหล่านั้น

FancyX='\[\342\234\]\227'
Checkmark='\[\342\234\]\223'

มีเหตุผล. สิ่งที่ฉันเดาก็คือทุบตีนับอักขระ เนื่องจาก X ใช้ถ่านหนึ่งตัว แต่เขียนเป็น 3 ดังนั้นจึงต้องแนบ 2 ตัวเพื่อแก้ไขการนับ คำตอบ @blauhirn ยังได้อธิบายถึงวิธีการทำในการทำงานด้วยและ\001 \002
akostadinov

FYI นี่คือวิธีที่คุณค้นหาวิธีการส่งออกอักขระ Unicode แบบหลายไบต์ในรูปแบบนี้: stackoverflow.com/a/602924/520567
akostadinov
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.