Konteks dan Pertanyaan
Ada banyak cara untuk mewarnai lingkungan terminal dan shell. Output dari perintah individual, seperti ls
dan grep
, juga dapat diwarnai. Tidak secara langsung terkait tetapi yang menarik adalah gagasan bermain media di konsol tetapi ini tampaknya bergantung pada beberapa kerangka kerja (perpustakaan) di atas sistem windowing. Pertanyaan berikut ini semata-mata ditujukan pada bash
shell dan implementasinya dalam kerangka terminal Linux dan fondasinya.
Harap pertimbangkan montase "rendering" ASCII berikut dari sebuah adegan dalam game 2D :
Ini bukan adegan yang dibuat secara acak. Segmen yang saya pilih semua sebenarnya menggambarkan beberapa bentuk medan "padang rumput" (pohon, semak & semak, bunga, rumput, dll.) Dari permainan yang menggunakan karakter ASCII untuk mewakili objek tersebut. 4 adegan terakhir menampilkan pengguna membuat tileset yang pada dasarnya adalah remap dari karakter ASCII dengan spesifikasi warna (detail seperti itu sepele - cukup untuk mengatakan bahwa ini adalah inspirasi visual untuk apa yang saya coba capai di sini dalam hal visual dan " pola").
Fitur umum adegan-adegan dalam berbagi montase adalah:
- Paling banyak 5-6 karakter ASCII berbeda (koma, tanda kutip dan beberapa lainnya)
- 2-4 warna yang digunakan
- untuk karakter
- untuk latar belakang karakter dalam beberapa kasus - contoh terakhir ada untuk menunjukkan penggunaan nuansa warna dengan sedikit atau tanpa karakter untuk membuat pola yaitu mosaik warna
Apa yang saya miliki di VM saat ini adalah Arch Linux dan meskipun pertanyaannya tidak spesifik distribusi, saya sudah melihat dokumentasi mereka untuk menyesuaikan /etc/bash.bashrc
file. Saya dapat melihat bahwa banyak penjelasan menjelaskan konfigurasi tampilan prompt dan umumnya semua elemen latar depan. Ada sedikit informasi tentang konfigurasi apa pun untuk latar belakang, kecuali biasanya untuk warna solid, seperti pengaturan dan tips ini :
# Background
On_Black='\e[40m' # Black
On_Red='\e[41m' # Red
On_Green='\e[42m' # Green
On_Yellow='\e[43m' # Yellow
On_Blue='\e[44m' # Blue
On_Purple='\e[45m' # Purple
On_Cyan='\e[46m' # Cyan
On_White='\e[47m' # White
Saya masih belum memahami secara konseptual apa "spasi" kosong / kosong / latar belakang yang tidak saya ketikkan ketika saya menggunakan konsol, yaitu "terbuat dari apa?" boleh dikatakan. Terutama mereka yang tidak pada prompt, dan yang membungkus perintah yang digaungkan. Sehubungan dengan apa yang terjadi pada jalur aktif, dimungkinkan untuk menunjukkan bahwa bash
bertindak dengan cara "berorientasi garis" dan bahwa beberapa operasi memicu pembersihan jalur aktif ( for i in $(seq 1 $(expr $(tput lines) \* $(tput cols))); do echo -n M; done; tput cup 15 1
, kemudian pada tipe prompt char dan backspace itu - diperagakan kontributor) - sejauh mana dapat bervariasi dari CLI ke yang lain yaitu zsh. Selain itu, sepertinya ketika saya menambahkan sesuatu seperti \[\033[44m\]
ke baris PS1 saya di bash.bashrc
saya mendapatkan latar belakang biru setelah memuat ulang bash - jadi jelas saya tahu bahwa ada beberapaLeverage di sini selama penampilan output sejauh latar belakang yang bersangkutan.
Tapi saya juga tahu bahwa bash adalah perangkat lunak yang mengandalkan beberapa fasilitas lain dalam bentuk subsistem TTY untuk membawa sesuatu ke layar - dan ini turun dari sana ke komponen VT di kernel yang saya asumsikan. pstree -Ap
pada Arch show yang systemd
ditautkan ke login
dan kemudian ke bash
.
The Arch Linux distribusi bergantung pada agetty
layanan TTY. Sederhana echo $TERM
akan menghasilkan jenis terminal yang digunakan ("linux" di sini di luar DE mana pun) dan infocmp[-d spec1 spec2]
perintah tanpa parameter menunjukkan kemampuan terminal aktif dan informasi profil dari terminal terminal terminfo (5) :
# Reconstructed via infocmp from file: /usr/share/terminfo/l/linux
linux|linux console,
am, bce, ccc, eo, mir, msgr, xenl, xon,
colors#8, it#8, ncv#18, pairs#64,
acsc=+\020\,\021-\030.^Y0\333'\004a\261f\370g\361h\260i\316j\331k\277l\332m\300n\305o~p\304q\304r\304s_t\303u\264v\301w\302x\263y\363z\362{\343|\330}\234~\376,
bel=^G, blink=\E[5m, bold=\E[1m, civis=\E[?25l\E[?1c,
clear=\E[H\E[J, cnorm=\E[?25h\E[?0c, cr=^M,
csr=\E[%i%p1%d;%p2%dr, cub=\E[%p1%dD, cub1=^H,
cud=\E[%p1%dB, cud1=^J, cuf=\E[%p1%dC, cuf1=\E[C,
cup=\E[%i%p1%d;%p2%dH, cuu=\E[%p1%dA, cuu1=\E[A,
cvvis=\E[?25h\E[?8c, dch=\E[%p1%dP, dch1=\E[P, dim=\E[2m,
dl=\E[%p1%dM, dl1=\E[M, ech=\E[%p1%dX, ed=\E[J, el=\E[K,
el1=\E[1K, flash=\E[?5h\E[?5l$, home=\E[H,
hpa=\E[%i%p1%dG, ht=^I, hts=\EH, ich=\E[%p1%d@, ich1=\E[@,
il=\E[%p1%dL, il1=\E[L, ind=^J,
initc=\E]P%p1%x%p2%{255}%*%{1000}%/%02x%p3%{255}%*%{1000}%/%02x%p4%{255}%*%{1000}%/%02x,
kb2=\E[G, kbs=\177, kcbt=\E[Z, kcub1=\E[D, kcud1=\E[B,
kcuf1=\E[C, kcuu1=\E[A, kdch1=\E[3~, kend=\E[4~, kf1=\E[[A,
kf10=\E[21~, kf11=\E[23~, kf12=\E[24~, kf13=\E[25~,
kf14=\E[26~, kf15=\E[28~, kf16=\E[29~, kf17=\E[31~,
kf18=\E[32~, kf19=\E[33~, kf2=\E[[B, kf20=\E[34~,
kf3=\E[[C, kf4=\E[[D, kf5=\E[[E, kf6=\E[17~, kf7=\E[18~,
kf8=\E[19~, kf9=\E[20~, khome=\E[1~, kich1=\E[2~,
kmous=\E[M, knp=\E[6~, kpp=\E[5~, kspd=^Z, nel=^M^J, oc=\E]R,
op=\E[39;49m, rc=\E8, rev=\E[7m, ri=\EM, rmacs=\E[10m,
rmam=\E[?7l, rmir=\E[4l, rmpch=\E[10m, rmso=\E[27m,
rmul=\E[24m, rs1=\Ec\E]R, sc=\E7, setab=\E[4%p1%dm,
setaf=\E[3%p1%dm,
sgr=\E[0;10%?%p1%t;7%;%?%p2%t;4%;%?%p3%t;7%;%?%p4%t;5%;%?%p5%t;2%;%?%p6%t;1%;%?%p7%t;8%;%?%p9%t;11%;m,
sgr0=\E[0;10m, smacs=\E[11m, smam=\E[?7h, smir=\E[4h,
smpch=\E[11m, smso=\E[7m, smul=\E[4m, tbc=\E[3g,
u6=\E[%i%d;%dR, u7=\E[6n, u8=\E[?6c, u9=\E[c,
vpa=\E[%i%p1%dd,
Seperti berdiri, banyak kemampuan dapat dimanfaatkan dari kerangka terminal dan pada dasarnya adalah fitur-fitur yang diekspos dalam file konfigurasi bash.bashrc sejauh prompt disesuaikan dengan mengatur variabel PS1. Sequence control dan escape digunakan untuk mengganggu aliran karakter yang ditampilkan di terminal untuk memasok fungsi, termasuk memindahkan kursor dan kemampuan lain yang dijelaskan dalam database informasi terminal. Banyak fungsi-fungsi yang dilewatkan dalam menggunakan Pengenalan Sequence Control terkenal ESC[
(atau \ 33) (urutan lebih lanjut di sini dan di sini , dan beberapa contoh ). Selain itu, dimungkinkan juga untuk menggunakantput
utilitas langsung pada CLI untuk mengubah beberapa properti terminal; misalnya tput setab 4
akan memiliki perintah bash echo pada latar belakang biru.
Jika kita strace bash
dapat melihat urutan melarikan diri dan perilaku dalam aksi:
write(2, "[il@Arch64vm1 ~]$ ", 19[il@Arch64vm1 ~]$ ) = 19 //bash starts
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
rt_sigprocmask(SIG_BLOCK, NULL, [], 8) = 0
read(0, " ", 1) = 1 //pressed <space>
rt_sigprocmask(SIG_BLOCK, [INT], [], 8) = 0
write(2, " ", 1 ) = 1
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
rt_sigprocmask(SIG_BLOCK, NULL, [], 8) = 0
read(0, "\177", 1) = 1 //pressed <backspace>...
rt_sigprocmask(SIG_BLOCK, [INT], [], 8) = 0
write(2, "\10\33[K", ) = 4 //triggers erasing the line
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
rt_sigprocmask(SIG_BLOCK, NULL, [], 8) = 0
read(0, "\33", 1) = 1 //pressed <esc> per se
Ini memberikan konteks untuk pertanyaan. Dapatkah ruang kosong / warna latar belakang di terminal diganti dengan set karakter ASCII acak (tapi cantik)? tetapi tidak tahu bagaimana menerapkan fitur atau apa yang saya cari di terminal.
Jadi saya telah membuat mockup mentah sebagai contoh bagaimana hasil akhirnya bisa terlihat jika ini mungkin (tidak serius :):
Pada dasarnya semua "ruang kosong" di terminal akan diisi dengan pola (di sini saya "ubin" salah satu gambar dari atas tetapi saya ingin dalam implementasi aktual untuk setiap individu "kosong" yang akan dihasilkan secara acak dari set 5-6 karakter dan fitur yang didokumentasikan dari montase yang akan ditentukan). Ada pola yang berbeda untuk baris perintah aktif yaitu bergelombang "air" tapi saya puas dengan garis yang berwarna biru. Seperti yang dibayangkan, perintah akan "menghapus" air "ketika mereka diketik pada baris aktif dan tentu saja kendala adalah bahwa pola karakter tidak pernah ditafsirkan oleh CLI kalau tidak akan membuatnya tidak berguna.
Jadi apakah ada konfigurasi yang diekspos dalam bash
atau dalam kerangka terminal yang tepat, atau skrip yang akan memungkinkan untuk menggunakan serangkaian karakter dan beberapa kontrol atas warna untuk memodifikasi output bash di terminal sehingga menghasilkan pola agak acak untuk latar belakang (yang akan mirip dengan apa yang saya tunjukkan di atas)? Atau haruskah saya cukup puas dengan sesuatu seperti mencoba untuk menyediakan gambar pola penuh sebagai latar belakang untuk tty ?
Implementasi
0,1 - Versi PatternOTD (kesepakatan sekali tembak saat Anda masuk)
Ungkapan berikut yang saya tambahkan ke file .bashrc saya menggabungkan beberapa gagasan yang kami jelajahi dan merupakan bukti konsep dasar untuk visual di terminal linux standar:
for i in $(seq 1 $(expr $(tput lines))); do echo -en '\E[32;32m'$(tr -dc '",.;:~' < /dev/urandom | head -c $(tput cols)); done; tput cup 15; tput setab 4; echo -en "\E[2K"; tput setab 0
Pengamatan
- Itu jelas hanya sebuah perintah jadi tidak gigih yaitu itu menggulung saat perintah diketik
- Memilih untuk tidak secara acak mengacak pemilihan karakter yaitu
head -c 1
dengantput cols
mengalikan garis untuk memulai, yang akan mencetak karakter acak individual dari pilihan yang dikutip - karena terlalu lambat. Saya tidak berpikirrandom
menghasilkan bilangan bulat panjang (tput cols) tapi masih lebih cepat. Tentunya ini semua sangat boros tetapi berhasil. - Belum mengacak warna atau efek per karakter atau selain hijau itu karena seperti yang saya jelaskan rendering / pemrosesan masing-masing karakter secara individual terlalu lambat. Re: framebuffer?
- Saya senang melihat bahwa polanya tidak mengganggu penggunaan CLI dalam arti tidak ditafsirkan oleh CLI! (kenapa meskipun saya tidak bisa menjelaskan)
- Air hilang terlalu cepat! ;-)
0,2 - PROMPT_COMMAND pekerjaan hack
Nilai variabel PROMPT_COMMAND diperiksa sebelum Bash mencetak setiap prompt utama. Saya tahu biasanya Anda akan menggunakan variabel untuk memanggil skrip di mana Anda dapat memproses elemen dari tampilan dll. Tapi saya lebih suka mencoba melakukan ini secara langsung dalam file .bashrc saya. Awalnya saya pikir saya bisa menerapkan beberapa kesadaran posisi yaitu di mana kursor sebelum eksekusi (jadi saya bisa menampilkan hal-hal di layar di mana saja dengan tput
kemudian kembali ke posisi saya sebelumnya, menggunakan sesuatu seperti ini untuk mengekstrak posisi:
stty -echo; echo -n $'\e[6n'; read -d R x; stty echo; echo ${x#??} //value is in x;x format so...
Saya akan pipa nilai ke cut -f1 -d";"
. Saya bisa melakukan ini pada CLI tetapi membuat ini bekerja di dalam urutan elemen dalam variabel PS1 / P_C berada di luar jangkauan saya saat ini dan mungkin saja perintah apa pun yang dimasukkan ke dalam PROMPT_COMMAND mungkin tidak dievaluasi pada setiap carriage return melainkan hanya sekali (?) meskipun dieksekusi setiap waktu (lihat pengamatan di bawah).
Jadi yang terbaik yang bisa saya lakukan adalah meneruskan urutan awal saya dan menambahkan beberapa perintah ke PROMPT_COMMAND dan definisi variabel PS1 dalam .bashrc. Seperti itu:
PROMPT_COMMAND="echo -en '\E[32;32m'$(tr -dc ',.:~' < /dev/urandom | head -c $(echo "$[$(tput cols) * 2]"))"
PS1="$(echo -en '\n') $(tput setab 4)$(echo -en "\E[2K")$(tput setab 0)\[\033[7;32m\]df:\[\033[1;34m\] \W @d \[\033[0m\]\e[32m"
for i in $(seq 1 $(expr $(tput lines))); do echo -en '\E[32;32m'$(tr -dc '",.;:~' < /dev/urandom | head -c $(tput cols)); done; tput cup 1; tput setab 4; echo -en "\E[2K"; tput setab 0
Singkatnya saya menggunakan P_C untuk mencoba menerapkan pola visual yang bertahan yaitu 2 baris ditambahkan. Sayangnya saya tidak dapat berhasil membuat kedua pola ini sambil mengulangi trik "air" saya yaitu memiliki garis biru aktif (yang hanya mengubah warna latar belakang, melakukan garis yang jelas, kemudian mengubah latar belakang kembali ke hitam). Saya telah mengumpulkan gambar untuk menunjukkan bagaimana ini dimainkan bersama:
Pengamatan
- Menggunakan backspace pada garis masih memicu perilaku garis yang jelas dan warna biru hilang
- Setiap kali tombol enter ditekan, kami memiliki 2 garis pola sebelum garis aktif yang baru
- Tentu saja seperti yang kita lihat lebih jauh ke bawah meskipun ada garis tambahan kita tidak membungkus pola di sisi perintah seperti
ls
- / dev / urandom's randomness nampaknya tidak begitu acak ketika dipanggil di sini di P_C. Gambar ini terdiri dari 2 gambar, tetapi mudah untuk mengambil bahwa pola 2 garis tambahan selalu sama yaitu keacakan tidak dihasilkan dengan setiap penekanan tombol masuk tetapi hanya satu kali untuk masing-masing dari dua garis - mungkin hanya yang pertama waktu .bashrc dibaca oleh
bash
. - Isi dari variabel PS1 dimulai dengan
$(echo -en '\n') $(tput setab 4)
- baik ruang di tengah sana, tepat sebelum $ (tput ...), itu HARUS ada di sana untuk ini untuk bekerja. Kalau tidak, garis biru muncul di atas prompt dan tidak di depannya dan saya tidak bisa menyelesaikannya. Dan retasan inilah yang memberikan namanya menjadi 0,2. :)
0,3 - tput cuu
&tput cud
for i in $(seq 1 $(expr $(tput lines))); do echo -en '\E[0;32m'$(tr -dc '",.o;:~' < /dev/urandom | head -c $(tput cols)); done; tput cup 1
PROMPT_COMMAND="echo -en '\033[0;32m$(tr -dc ',;o.:~' < /dev/urandom | head -c $(tput cols))\n\033[36;44m$(tr -dc '~' < /dev/urandom | head -c $(tput cols))\033[0;32m$(tr -dc ',.o+;:~' < /dev/urandom | head -c $(tput cols))'$(tput cuu 2)"
PS1="\[\033[0m\] \[\033[1;32m\][1]\[\033[7;32m\]=2=:\W)\[\033[0;32m\]=3=\[\033[1;32m\]=4=@>\[\033[0;32m\]"
Apa yang dilakukan dengan PROMPT_COMMAND adalah bahwa 3 garis pola dicetak setiap kali sebelum prompt dibuat - dan 3 set pola tersebut dihasilkan secara individual dalam batasan yang dijelaskan dalam 0.2 - tidak berarti untuk air karena 1 karakter tetapi masih. Kemudian kita naik dua baris (menggunakan tput cuu 2
) dan prompt dihasilkan pada garis tengah sesuai dengan PS1. Kami masih memiliki set perintah awal kami untuk pola layar penuh pada .bashrc load yang dieksekusi hanya sekali ketika kita masuk ke terminal. Sekarang kami memiliki beberapa lapisan di sekitar garis aktif yang memiliki pola biru sendiri yang selalu berulang ketika ada kereta kembali. Isi variabel PS1 dan P_C telah disanitasi. Sintaks dari urutan melarikan diri dan kode warna tertanam dalam waktu lamaecho
urutannya bisa rumit. Kesalahan menyebabkan perilaku terminal yang anehtermasuk baris yang saling menimpa, prompt yang muncul jauh dari margin kiri atau output yang tidak biasa ke hal-hal yang telah diproses secara tidak sengaja. Suatu kondisi ada dengan apa yang saya lakukan, di mana ruang tambahan diperlukan di dalam variabel PS1 untuk melawan perbedaan visual antara terminal linux dan lxterm dengan pengaturan saya (Arch Bang). Tanpa ruang ekstra, terminal linux mencetak karakter pertama dari prompt di akhir baris terakhir untuk beberapa alasan yang tidak dapat saya pahami (tentu saja itu adalah sesuatu yang saya lakukan dan bukan perilaku default). Juga tidak tahu bagaimana menghasilkan beberapa efek acak (tebal, terbalik, dll) ke kumpulan karakter dalam tanda kutip, karena diputuskan sejak awal untuk menghasilkan string yang lebih panjang untuk meningkatkan kinerja.
Pola awal saat terminal terbuka
Perilaku setelah a clear
dan menekan masuk berturut-turut saat diminta
Pengamatan
- Harus dirancang ulang atau dimodifikasi untuk menerapkan pewarnaan pola di luar melakukannya secara massal
- Mulai merasa bahwa melangkah lebih jauh akan membutuhkan baik memasukkan semua itu ke dalam skrip atau memanfaatkan beberapa bentuk abstraksi yang lebih tinggi. Tetapi kapabilitas terminal cukup memungkinkan bagi pengguna akhir (mengingatkan saya pada "logo")!