Gilles mengidentifikasi masalah utama Anda, tetapi saya ingin mencoba menjelaskannya secara berbeda.
Bash menginterpretasikan prompt khusus lolos hanya sebelum memperluas variabel apa pun dalam prompt. Ini berarti bahwa menggunakan \e
dalam variabel yang diperluas dari prompt tidak berfungsi, meskipun itu berfungsi langsung di PS1
.
Misalnya, ini berfungsi seperti yang diharapkan, dan memberikan teks merah:
PS1='\e[1;31m this is in red '
Tapi ini tidak, itu hanya menempatkan literal \e
di prompt:
RED='\e[1;31m'
PS1="$RED not in red "
Jika Anda ingin menyimpan warna lolos dalam variabel, Anda dapat menggunakan ANSI-C mengutip ( $'...'
) untuk menempatkan karakter escape literal dalam variabel.
Untuk melakukan ini, Anda dapat mengubah definisi Anda tentang GREEN
, RED
dan NONE
, sehingga nilai mereka adalah urutan escape yang sebenarnya.
GREEN=$'\033[1;32m'
RED=$'\033[1;31m'
NONE=$'\033[m'
Jika Anda melakukan itu, PS1
tanda kutip pertama Anda dengan single harus bekerja:
PS1='${RED}\h $(get_path) ${exitStatus}${NONE} '
Namun, maka Anda akan memiliki masalah kedua.
Coba jalankan itu, lalu tekan Up Arrow, lalu Home, dan kursor Anda tidak akan kembali ke awal baris.
Untuk memperbaikinya, ubah PS1
untuk memasukkan \[
dan \]
sekitar urutan pelarian warna, misalnya
PS1='\[${RED}\]\h $(get_path) $?\[${NONE}\] '
Anda tidak dapat menggunakan get_exit_status
dengan benar di sini, karena outputnya berisi karakter pencetakan (kode keluar) dan non-cetak (kode warna), dan tidak ada cara untuk menandainya dengan benar di prompt. Menempatkan \[...\]
akan menandainya sebagai non-pencetakan secara penuh, yang tidak benar. Anda harus mengubah fungsi sehingga hanya mencetak kode warna yang tepat, dan kemudian mengelilinginya \[...\]
di prompt.
\[
adalah\1
, dan\[
sekarang\2
. Mereka yang sesuai dengan beberapaRL_PROMPT_{START,END}_IGNORE
hal readline yang memintanya untuk mengabaikan byte saat menghitung panjang prompt di layar. Lihat lists.gnu.org/archive/html/bug-bash/2015-08/msg00027.html .