Mengapa bash prompt ini terkadang menyimpan bagian dari perintah sebelumnya saat menggulir riwayat?

29

Bash prompt saya, yang saya akui telah dicuri dari beberapa tempat dan dirakit bersama, terkadang akan menambahkan bagian dari perintah sebelumnya hingga panjang ketika menggulir sejarah bash dengan panah atas / bawah.

Misalnya, jika perintah saya sebelumnya adalah:

ls
cd /home/caleb
vim .bashrc

Ketika saya berada di prompt saya dan menggulir ke atas dua kali mungkin terlihat seperti:

$ vim .bcd / home / caleb

Di mana lima karakter pertama tersisa dari perintah terakhir.

Adakah yang tahu mengapa ini terjadi, dan bagaimana itu bisa dihentikan?

Prompt saya diset dengan kode ini (cara lama untuk memasukkan di sini): https://gist.github.com/1679352

Caleb Thompson
sumber
1
Atur PS1 ke nilai tanpa omong kosong vcs keseluruhan dan lihat apa yang terjadi. Itu dugaanku.
Daniel Beck
Apakah Anda sudah menemukan pelakunya di prompt Anda? Saya mengalami masalah yang sama.
acme
Ya bash kehilangan warna, dan tidak dapat memisahkan panjang string dengan warna keluar dari panjang string yang terlihat. Inilah yang SiegeX maksudkan. Saya akhirnya beralih ke ZSH dan menggunakan prompt yang berbeda. ZSH tidak memiliki masalah yang sama.
Caleb Thompson
1
Kedua jawaban sebelumnya tidak menyelesaikan masalah saya, dan tidak memberikan penjelasan mengapa ini terjadi. Silakan periksa Custom Bash prompt menimpa dirinya sendiri , jika ada yang mencari ke titik ini.
D3Hunter
Masalah terkait unix.stackexchange.com/questions/105958/…
matthiasbe

Jawaban:

6

Di suatu tempat prompt Anda adalah fubar. Apa yang biasanya terjadi adalah bahwa shell Anda menganggap kode istilah yang dihasilkannya tidak dapat dicetak dan mengharapkannya mengambil ruang. Saran terbaik yang dapat saya berikan kepada Anda adalah menambahkan (atau menghilangkan) prompt Anda secara sistematis hingga perilaku ini berhenti untuk mengisolasi kode yang menyebabkan masalah ini.

SiegeX
sumber
37

Kode warna harus dibungkus dengan tanda kurung. Tanda kurung menginformasikan kepada bash bahwa teks terlampir tidak boleh dicetak

menggunakan contoh @ Phreditor, ini menunjukkan bahwa pemformatan yang dilakukan setelah baris baru akan menghasilkan masalah asli:

export PS1="\n\n\[\033[01;33m[\w]\033[00m\n\033[0;90m\$ "

membungkus kode format dalam [] memastikan bahwa perilaku menjengkelkan tidak pernah terjadi:

export PS1="\n\[\[\033[01;33m\][\w]\[\033[00m\]\n\[\033[0;90m\]\$ "

Dokumentasi: http://tldp.org/HOWTO/Bash-Prompt-HOWTO/nonprintingchars.html

Karena pemformatan PS1 menyebabkan nilainya terlalu panjang dan sulit dibaca, saya meletakkan kode format dalam variabel:

BYELLOW='\[\033[01;33m\]'
IBLACK='\[\033[0;90m\]'
PS_CLEAR='\[\033[0m\]'
export PS1="\n${BYELLOW}[\w]${PS_CLEAR}\n${IBLACK}\$ "
m79lkm
sumber
3
Ini harus menjadi jawaban yang diterima. Apakah memecahkan masalah.
Atcold
1
Harus dicatat (karena saya gagal mencatatnya;)), bahwa dalam kekacauan garis miring terbalik dan tanda kurung siku, tanda kurung siku yang mengikuti urutan pelarian \033TIDAK boleh diloloskan. Hanya tanda kurung siku yang harus diloloskan.
Benjam
Cara membingungkan bagi saya untuk berurusan dengan semua karakter khusus itu, menggunakan hasil google pertama membantu menghasilkan prompt kerja persis seperti yang saya inginkan: ezprompt.net
Mallox
Saya ingin menyesuaikan warna cepat saya selama bertahun-tahun, tetapi tidak pernah sejak saya selalu memiliki masalah ini! Saya tidak pernah tahu mengapa jadi saya berhenti dan menjaga semuanya tetap putih ... Saya baru saja menyiapkan komputer baru dan akhirnya saya sadar bahwa sebenarnya Google masalah untuk sekali ... Senang sekali saya melakukannya! Terima kasih atas pelajaran yang luar biasa ini.
TylerH4
8

Saya memiliki masalah yang sama dan itu terkait dengan definisi warna.

Dalam kasus saya, saya memiliki prompt multi-line (memberikan sebagian besar ruang untuk perintah saat ini terlepas dari panjang jalur yang ditampilkan oleh prompt).

Versi buruk:

export PS1="\n\n\[\033[01;33m[\w]\n\033[00m\$ "

Versi bagus:

export PS1="\n\n\[\033[01;33m[\w]\033[00m\n\$ "

\033[00mmengakhiri warnanya. Jika setelah baris baru ( \n), itu mencegah redraw yang tepat di terminal, untuk menimpa perintah sebelumnya dengan warna latar belakang. Memindahkannya di belakang baris baru menyelesaikan masalah.

(menggunakan Terminal di Mac OS 10.8)

Pengacara
sumber
Ini menunjukkan masalah bagi saya, sementara jawaban yang diterima saat ini terlalu umum.
Brian
Ini adalah jawaban yang lebih tepat dan harus menjadi pemenang (dan juga solusi untuk masalah saya).
craveytrain
yang \nberada pelakunya bagi saya juga. Terima kasih!
mhulse
3

Saya benar-benar berpikir ini ada hubungannya dengan pembatas 'karakter non-cetak' yang hilang. Saya memiliki masalah yang persis sama, tetapi memindahkannya sebelum baris baru (\ n) tidak memperbaikinya. Alih-alih, saya benar mengelilingi semua karakter non-cetak (di sini, perintah pewarnaan) dengan '\ [' dan '\]'.

Buruk (berfungsi, tetapi memiliki masalah penumbukan sejarah yang dijelaskan di atas):

PS1="\e[32m\u\e[35m@\e[32m\h \e[33m\w\e[36m\n\$\e[0m"

Bagus (dikelilingi semua perintah warna dengan '\ [' dan '\]' - tidak menampilkan riwayat perintah tumbuk):

PS1="\[\e[32m\]\u\[\e[35m\]@\[\e[32m\]\h \[\e[33m\]\w\[\e[36m\]\n\$\[\e[0m\]"

i.e. "\e[...m" --becomes--> "\[\e[...m\]"

Dan jika Anda memasukkan ini ke dalam sesuatu seperti SecureCRT untuk mengirim secara otomatis saat masuk ke suatu sistem, Anda mungkin harus melipatgandakan semuanya (menempatkan backslash ganda di mana-mana) jika sistem login otomatis mengkonsumsi backslash pertama sendiri untuk menentukan karakter yang akan dikirim :

PS1="\\[\\e[32m\\]\\u\\[\\e[35m\\]@\\[\\e[32m\\]\\h \\[\\e[33m\\]\\w\\[\\e[36m\\]\\n\\$\\[\\e[0m\\]"

i.e. "\..." --becomes--> "\\..."

(Ini pasti benar untuk SecureCRT dan mungkin benar untuk orang lain, seperti Putty atau TeraTerm - pengujian diperlukan pada bagian Anda.)

skeetastax
sumber