Di saya .bashrc
, saya menggunakan kode warna terminal ANSI untuk mewarnai berbagai bit. Ini terlihat seperti ini:
PS1='\u@\h:\w\[\033[33m\]$(virtual_env)\[\033[32m\]$(git_branch)\[\033[0m\]$ '
di mana virtual_env
dan git_branch
adalah fungsi bash yang menampilkan barang di stdout.
Sekarang, untuk membuatnya lebih mudah dibaca dan dimodifikasi, saya ingin menyimpan kode warna dalam variabel dan merujuknya, alih-alih menanamkannya langsung ke PS1
. Jadi saya punya banyak variabel seperti ini:
GREEN="\[\033[32m\]"
YELLOW="\[\033[33m\]"
RESET="\[\033[0m\]"
Saya ingin dapat menulis sesuatu seperti:
PS1='\u@\h:\w${YELLOW}$(virtual_env)${GREEN}$(git_branch)${RESET}$ '
Tapi ini tidak berhasil - kode warna muncul di prompt, seperti mereka melarikan diri. Warna berfungsi dengan benar jika saya menggunakan tanda kutip ganda sebagai gantinya PS1
, tapi kemudian prompt hanya berubah ketika saya melakukannya source ~/.bashrc
.
Saya sudah mencoba hal-hal lain saya pernah melihat orang melakukan - menggunakan printf
, menggunakan tanda kutip tunggal untuk warna, menempatkan \[
dan \]
di PS1
bukannya variabel warna, tapi sepertinya tidak ada pekerjaan.
Bagaimana saya bisa menggunakan variabel untuk kode warna?
sumber
.bashrc
?Jawaban:
Solusinya adalah untuk mendapatkan shell untuk menggantikan variabel warna ketika mendefinisikan prompt, tetapi bukan fungsinya. Untuk melakukan ini, gunakan tanda kutip ganda seperti yang Anda coba semula, tetapi lepas dari perintah sehingga mereka tidak dievaluasi sampai prompt ditarik.
Perhatikan
\
sebelum$()
pada setiap perintah.Jika kita menggema ini, kita melihat:
Seperti yang Anda lihat, variabel warna dapat diganti, tetapi bukan perintahnya.
sumber
Masalahnya adalah bahwa variabel Anda
GREEN
berisi string literal yang terdiri dari "braket backslash backslash nol tiga tiga" dan seterusnya. Itu tidak mengandung misalnya karakter pelarian ASCII seperti yang diperlukan untuk membuat terminal Anda berubah warna.Anda dapat menempatkan karakter kontrol ke dalam
GREEN
(danYELLOW
danRESET
) secara manual, tetapi pilihan yang jauh lebih baik adalah menggunakantput
di tempat pertama sehingga Anda tidak perlu melakukan hard code apa pun dan Anda akan mendukung semua jenis terminal.Alasan mengapa itu dunia ketika Anda menempatkan "backslash nol tiga tiga" dll ... langsung ke
PS1
adalah bahwa interpretasi urutan backslash tertentu adalah fitur bisikan bash (lihat bagian PROMPTING dalam manual. Substitusi ini terjadi sebelum ekspansi parameter, perintah substitusi, ekspansi aritmatika, dan penghapusan kutipan, jadi itu tidak diterapkan pada hasil semua operasi lainnya.sumber
\[\]
dalam$PS1
. Sebagai contoh:PS1='\u@\h:\w\[${YELLOW}\]'
. Jika Anda tidak melakukan ini, dan Anda berakhir dengan perintah panjang yang membungkus ke baris berikutnya, Anda akan menghadapi segala macam masalah. Shell menggunakan\[\]
untuk menentukan karakter mana yang tidak dapat dicetak, sehingga tidak memasukkan mereka ke dalam perhitungan panjang prompt. Perlu ini sehingga dapat menarik garis dengan benar ketika melebihi lebar terminal.tput
, terima kasih. Saya akan menggunakan jawaban Patrick untuk saat ini tetapi saya akan mengunjungi ini lagi ketika saya mendapat kesempatan.Ubah cara Anda mengisi $ GREEN, $ YELLOW, dan $ RESET:
sumber
\[…\]
kebutuhan bit untuk tetap berada di prompt, Anda tidak dapat hal itu dalam variabel. Anda telah menghapusnya sama sekali, yang akan menyebabkan masalah tampilan (kursor tidak berada pada posisi di mana bash mengharapkannya).tput setaf
jangan biarkan Anda memilih dari set warna "cahaya", seperti cyan cahaya. @ Cyrus menjawab, namun, tidak.