Czy puste miejsca / tło w terminalu można zastąpić losowym (ale ładnym) wzorem znaków ASCII?

23

Kontekst i pytanie

Istnieje wiele sposobów pokolorowania środowiska terminala i powłoki. Dane wyjściowe poszczególnych poleceń, takich jak lsi grep, można również pokolorować. Nie jest bezpośrednio powiązane, ale interesujące jest pojęcie odtwarzania multimediów na konsoli, ale wydaje się, że opiera się ono na niektórych ramach (bibliotekach) na systemie okienkowym. Poniższe pytanie dotyczy wyłącznie bashpowłoki i jej implementacji w frameworku terminali Linux i jego podstawach.

Proszę rozważyć następujący montaż „renderingów” ASCII sceny w grze 2D :

Scena przyrodnicza (drzewa, krzewy, kwiaty, trawa) z gry Dwarf Fortress - pierwsze 2 ekrany pokazują grę bez zestawu klocków (tylko ASCII), trzeci ekran jest generowany za pomocą zestawu klocków Vherid, kolejne 2 ekrany są generowane za pomocą Zestaw klocków CLA, a ostatni ekran jest generowany za pomocą zestawu klocków Jolly Bastion

To nie są losowo generowane sceny. Wszystkie wybrane przeze mnie segmenty przedstawiają jakąś formę „trawiastego” terenu (drzewa, krzewy i krzewy, kwiaty, trawa itp.) Z gry, w której do reprezentowania takich obiektów używane są postacie ASCII. Ostatnie 4 sceny przedstawiają zestawy klocków wykonane przez użytkownika, które są w zasadzie remapiem znaków ASCII ze specyfikacjami kolorów (takie szczegóły są banalne - wystarczy powiedzieć, że jest to wizualna inspiracja do tego, co próbuję osiągnąć tutaj pod względem wizualnym i „ wzór").

Wspólne cechy tych scen w udziale montażowym to:

  • Maksymalnie 5-6 różnych znaków ASCII (przecinki, znaki cudzysłowu i kilka innych)
  • Zastosowano 2-4 kolory
    • dla postaci
    • dla tła postaci w niektórych przypadkach - ostatnim przykładem jest pokazanie użycia odcieni kolorów z niewielką liczbą znaków lub bez znaku w celu utworzenia wzoru, tj. kolorowej mozaiki

To, co mam w tej chwili na maszynie wirtualnej, to Arch Linux i chociaż pytanie nie jest specyficzne dla dystrybucji, zajrzałem do ich dokumentacji w celu dostosowania /etc/bash.bashrcpliku. Widzę, że wiele wyjaśnień dotyczy konfiguracji wyglądu monitu i ogólnie wszystkich elementów pierwszego planu. Istnieje niewiele informacji na temat dowolnej konfiguracji tła, z wyjątkiem zwykle jednolitego koloru, takich jak te ustawienia i wskazówki :

# 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

Nadal nie rozumiem koncepcyjnie tych „pustych / pustych / tła” „spacji”, których nie wpisałem podczas korzystania z konsoli, tj. „Z czego są zrobione?” że tak powiem. Zwłaszcza te, które nie są wyświetlane w wierszu poleceń i które zawierają polecenia, które są powtarzane. W odniesieniu do tego, co dzieje się na linii aktywnej, można wykazać, że bashdziała ona w sposób „zorientowany na linię” i że niektóre operacje wyzwalają czyszczenie linii aktywnej ( for i in $(seq 1 $(expr $(tput lines) \* $(tput cols))); do echo -n M; done; tput cup 15 1, a następnie po znaku zachęty wpisz znak i cofnij ją - pokazano współpracownik) - którego zakres może się różnić w zależności od CLI, np. zsh. Co więcej, wydaje się, że gdy dodam coś \[\033[44m\]do mojej linii PS1, bash.bashrcpo przeładowaniu dostaję niebieskie tło - więc oczywiście wiem, że jest trochęwykorzystać tutaj wygląd wyjściowy, o ile dotyczy to tła .

Ale wiem też, że bash to oprogramowanie polegające na jakimś innym narzędziu w postaci podsystemu TTY do przenoszenia rzeczy na ekran - i od tego momentu przechodzi do komponentu VT w jądrze, które zakładam. pstree -Apna Arch pokazuje, systemdpowiązane z, logina następnie z bash.

Arch Linux dystrybucja opiera się agettyna usługi TTY. Prosty echo $TERMda typ używanego terminala („linux” tutaj poza dowolnym DE), a infocmp[-d spec1 spec2]polecenie bez parametru pokazuje aktywne możliwości terminala i informacje o profilu z bazy terminali 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,

Na obecnym etapie, wiele możliwości może być wykorzystanych z frameworku terminali i są to w zasadzie te funkcje, które są ujawnione w pliku konfiguracyjnym bash.bashrc, o ile monit jest dostosowywany poprzez ustawienie zmiennej PS1. Sekwencje kontrolne i sekwencje specjalne służą do przerwania przepływu wyświetlania znaków w terminalu w celu dostarczenia funkcji, w tym przesunięcia kursora i innych możliwości opisanych w bazie danych informacji o terminalu. Wiele z tych funkcji jest przekazywanych przy użyciu dobrze znanego ESC[(lub \ 33) Kontrolera sekwencji wprowadzającej (więcej sekwencji tutaj i tutaj oraz kilka przykładów ). Ponadto można również korzystać ztputnarzędzie bezpośrednio w interfejsie CLI do zmiany niektórych właściwości terminala; na przykład tput setab 4będą miały polecenia echa bash na niebieskim tle.

Jeśli strace bashwidzimy zarówno sekwencje specjalne, jak i zachowanie w akcji:

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

To stanowi kontekst dla pytania. Czy puste miejsca / kolor tła w terminalu można zastąpić losowym (ale ładnym) zestawem znaków ASCII? ale nie ma pojęcia, jak zaimplementować funkcje ani czego szukam w terminalu.

Więc stworzyłem prymitywną makietę jako przykład tego, jak mógłby wyglądać efekt końcowy, gdyby to było możliwe (nie poważnie :):

Makieta terminala wyświetlającego zestaw kolorowych znaków ASCII jako tło zamiast jednolitego czarnego koloru.  Wzorzec jest zawijany wokół wyniku wykonanych poleceń.  Aktywny wiersz poleceń ma inny wzór / kolor, ale ten wzór nigdy nie jest interpretowany przez CLI w celu zachowania pełnej funkcjonalności powłoki

Zasadniczo cała „pusta przestrzeń” w terminalu byłaby wypełniona wzorem (tutaj „kafelkuję” jeden z obrazków z góry, ale chciałbym, aby w rzeczywistej implementacji dla każdego „pustego” miejsca generować losowo z zestawu 5-6 znaków i cech udokumentowanych z montażu, które zostaną określone). Aktywny wiersz poleceń ma inny wzór, tj. Falistą „wodę”, ale zadowoliłbym się, że linia jest niebieska. Jak to można sobie wyobrazić, polecenia „wymażą” „wodę”, gdy zostaną wpisane w aktywnym wierszu, i oczywiście istnieje ograniczenie, że wzór znaków nigdy nie zostanie zinterpretowany przez CLI, w przeciwnym razie uczyni go bezużytecznym.

Czy istnieje jakakolwiek konfiguracja ujawniona w bashlub we właściwej strukturze terminala, lub skrypt, który pozwoliłby użyć zestawu znaków i pewnej kontroli kolorów, aby zmodyfikować wyjście bash w terminalu, aby wygenerować nieco losowy wzór tła (co byłoby podobne do tego, co pokazałem powyżej)? Czy powinienem po prostu zadowolić się próbą dostarczenia pełnego obrazu wzoru jako tła dla tty ?

Realizacje

0.1 - Wersja PatternOTD (jedna transakcja po zalogowaniu)

Następujące wyrażenie, które dodałem do mojego pliku .bashrc, łączy niektóre z pojęć, które badaliśmy i stanowi (bardzo) podstawowy dowód koncepcji wizualnej w standardowym terminalu linux:

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

wprowadź opis zdjęcia tutaj

Spostrzeżenia

  • To oczywiście tylko polecenie, więc nietrwałe, tzn. Przewija się w miarę wpisywania poleceń
  • Zdecydowano się nie losować pojedynczo losowego wyboru znaków, tj head -c 1. tput colsPrzez pomnożenie wierszy na początku, co spowoduje wydrukowanie pojedynczych losowych znaków z cytowanego zaznaczenia - ponieważ jest zbyt wolny. Nie sądzę, że randomgeneruje długą liczbę całkowitą (tput cols), ale nadal jest szybsza. Z pewnością jest to bardzo marnotrawstwo, ale działa.
  • Nie losowałem żadnego koloru ani efektu na znak, ani w żaden inny sposób poza tym zielonym, ponieważ, jak wyjaśniłem, renderowanie / przetwarzanie każdego znaku osobno jest zbyt wolne. Odp: bufor ramki?
  • Cieszę się, że wzorzec nie koliduje z korzystaniem z CLI w tym sensie, że nie jest interpretowany przez CLI! (dlaczego nie mogłem tego wyjaśnić)
  • Woda za szybko wypłynęła! ;-)

0.2 - PROPOZYCJA HAKOWANIA PROMPT_COMMAND

Wartość zmiennej PROMPT_COMMAND jest sprawdzana tuż przed wydrukowaniem przez Bash każdego głównego monitu. Wiem, że zwykle używasz zmiennej do wywołania skryptu, w którym możesz przetwarzać elementy z wyświetlacza itp., Ale raczej próbuję to zrobić bezpośrednio w moim pliku .bashrc. Początkowo myślałem, że mogę wdrożyć trochę świadomości pozycyjnej, tj. Gdzie jest kursor przed wykonaniem (więc mogłem renderować rzeczy na ekranie w dowolnym miejscu, a tputnastępnie powrócić do poprzedniej pozycji, używając czegoś takiego do wyodrębnienia pozycji:

stty -echo; echo -n $'\e[6n'; read -d R x; stty echo; echo ${x#??}  //value is in x;x format so...

Zmieniłbym wartość do cut -f1 -d";". Mogę to zrobić w interfejsie CLI, ale wykonanie tej pracy w sekwencji elementów w zmiennych PS1 / P_C jest obecnie poza moim zasięgiem i możliwe jest, że jakiekolwiek polecenie wprowadzone w PROMPT_COMMAND może nie być oceniane przy każdym powrocie karetki, ale raczej tylko raz (?) pomimo wykonania za każdym razem (patrz uwagi poniżej).

Więc najlepsze, co mogłem zrobić, to przenieść moją początkową sekwencję i dodać kilka poleceń zarówno do PROMPT_COMMAND, jak i definicji zmiennej PS1 w .bashrc. Tak jak:

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

Podsumowując, używam P_C do próby zaimplementowania trwałego wzorca wizualnego, tzn. Dodania 2 linii. Niestety nie udało mi się stworzyć obu tych wzorów, powtarzając moją sztuczkę „wodną”, tj. Mając niebieską linię aktywną (która po prostu zmienia kolor tła, robi wyraźną linię, a następnie zmienia tło z powrotem na czarny). Przygotowałem obraz, aby pokazać, jak to gra razem:

wprowadź opis zdjęcia tutaj

Spostrzeżenia

  • Użycie backspace na linii nadal wyzwala zachowanie czystej linii i niebieski zniknął
  • Za każdym naciśnięciem klawisza Enter mamy 2 linie wzoru przed nową linią aktywną
  • Oczywiście, jak widzimy dalej, pomimo dodatkowych linii, nie zawijamy wzoru z boku poleceń takich jak ls
  • Losowość / dev / urandom nie wydaje się tak losowa, gdy zostanie wywołana tutaj w P_C. Ten obraz składa się z 2 obrazów, ale łatwo jest zauważyć, że wzór 2 dodatkowych linii jest zawsze taki sam, tj. Losowość nie jest generowana przy każdym naciśnięciu klawisza Enter, ale tylko jeden raz dla każdej z dwóch linii - być może tylko pierwsza czas odczytu .bashrc bash.
  • Zawartość zmiennej PS1 zaczyna się od $(echo -en '\n') $(tput setab 4)- cóż, ta przestrzeń pośrodku, tuż przed $ (tput ...), MUSI tam być, żeby to zadziałało. W przeciwnym razie niebieska linia pojawi się na górze monitu, a nie przed nim, i nie mogę tego rozwiązać. A ten hack nadaje nazwę 0,2. :)

0,3 - tput cuuitput 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\]"

PROMPT_COMMAND polega na tym, że 3 wiersze wzorów są drukowane za każdym razem przed wygenerowaniem pytania - i te 3 zestawy wzorów są generowane indywidualnie w ramach ograniczeń wyjaśnionych w 0.2 - bez znaczenia dla wody, ponieważ ma 1 znak, ale nadal. Następnie przechodzimy w górę o dwie linie (za pomocą tput cuu 2) i monit jest generowany w środkowej linii zgodnie z PS1. Wciąż mamy nasz początkowy zestaw poleceń dla pełnego ekranu wzorca przy ładowaniu .bashrc, który jest wykonywany tylko raz, gdy logujemy się do terminala. Teraz mamy trochę wypełnienia wokół aktywnej linii, która ma swój własny niebieski wzór, który zawsze się powtarza, gdy jest karetka powrotna. Zawartość zmiennej PS1 i P_C zostały zdezynfekowane. Składnia sekwencji ucieczki i kodowania kolorów jest osadzona w długimechosekwencje mogą być trudne. Błędy prowadzą do dziwnego zachowania terminalaw tym wiersze, które się nadpisują, monit, który pojawia się z dala od lewego marginesu lub nietypowe wyjście do rzeczy przetworzonych przypadkowo. Z tym, co robię, istnieje warunek, w którym wymagana jest dodatkowa przestrzeń wewnątrz zmiennej PS1, aby zneutralizować wizualną różnicę między terminalem linux a lxterm przy mojej konfiguracji (Arch Bang). Bez dodatkowej spacji terminal linux wypisuje pierwszy znak zachęty na końcu ostatniego wiersza z jakiegoś powodu, którego nie mogę zrozumieć (oczywiście jest to coś, co robię, a nie zachowanie domyślne). Nie mogę również dowiedzieć się, jak wygenerować jakiś losowy efekt (pogrubienie, odwrotność itp.) Dla zestawu znaków w cudzysłowie, ponieważ wcześniej podjęto decyzję o generowaniu dłuższych ciągów w celu zwiększenia wydajności.

Początkowy wzór po otwarciu terminala wprowadź opis zdjęcia tutaj

Zachowanie po a cleari naciśnięciu klawisza Enter kolejno po znaku zachęty wprowadź opis zdjęcia tutaj

Spostrzeżenia

  • Powinny zostać przeprojektowane lub zmodyfikowane w celu wdrożenia kolorowania wzorów poza robieniem tego luzem
  • Zrozumienie, że pójście o wiele dalej będzie wymagało albo umieszczenia tego wszystkiego w skrypcie, albo wykorzystania wyższej formy abstrakcji. Ale możliwości terminalu są całkiem dostępne dla użytkownika końcowego (przypomina mi „logo”)!
Społeczność
źródło
20
Jestem trochę przerażony, że chcesz to zrobić :-)
Chris Down
2
@ Chris Down Tak jak ja naprawdę po ukończeniu Q, tak bardzo, że prawie nie opublikowałem;) To jest idiosynkratyczne, ale wierzę, że odpowiedź może przynieść pewien wgląd w to, jak rzeczy są wyświetlane w terminalu i czy wykracza to poza konfigurację i do zmiany przeznaczenia oprogramowania, czy nie. I chyba sezon wakacyjny!
3
Ja też jestem trochę przerażony, ale nie sądzę, żeby w pytaniu było coś złego. W przeszłości robiłem wiele okropnych rzeczy, ale starając się dokonać wspomnianych okrucieństw, sporo się nauczyłem. Plus, co jedna osoba uważa za szaloną, inna może nie. To brzmi jak dobre wyzwanie, idź do niego :-)
Patrick
Czy próbujesz to osiągnąć w konsoli tekstowej lub w buforze ramki? A może chcesz także wspierać Xterm?
Ruslan
@Ruslan Może oba ze względu na kompletność? Widzę, że SDL korzysta z bufora ramki z tego, co rozumiem, a gra, o której mówiłem, korzysta z tego frameworka. Z drugiej strony moje pytanie ma na celu przedstawienie klasycznych elementów wewnętrznych terminala. Kiedy bash jest dostosowywany, a elementy pierwszoplanowe zmieniane za pomocą bash.bashrc, nie ma potrzeby uciekania się do bufora ramki, więc jestem również bardzo zainteresowany „czymś, co działa na tekście” lub w inny sposób jest implementowany, tak nieefektywny lub naiwny, jak to może być być. Jeśli chodzi o Xterm, początkowo miałem na myśli rozwiązanie, które nie opiera się na X.

Odpowiedzi:

6

0,5a - równiny cyjanobiałka

Wcześniejsze implementacje dostarczone z pytaniem opierają się na sekwencji poleceń, które wykorzystują troraz na zestawie znaków jednobajtowych. Jak wyjaśniono w niniejszym pytaniu i odpowiedziach , narzędzie nie może przetwarzać znaków wielobajtowych, takich jak Unicode. Ale wykorzystanie tych postaci było bardzo istotne dla osiągnięcia pożądanego efektu. Zapewniono „rozwiązanie”, które pozwala mieszać znaki jednobajtowe i wielobajtowe w jednym strumieniu w celu renderowania. Opracowane tam rozwiązanie jest tutaj prezentowane i dostosowywane:

Z1=$(echo -en '\xe2\x97\x98') #◘ 1
Z2=$(echo -en '\xe2\x95\x9a') #╚ 2
Z3=$(echo -en '\xe2\x95\x9c') #╜ 3
Z4=$(echo -en '\xe2\x95\x9d') #╝ 4
Z5=$(echo -en '\xe2\x95\x9e') #╞ 5
Z6=$(echo -en '\xe2\x95\x9f') #╟ 6
Z7=$(echo -en '\xe2\x96\x91') #░ 7
Z8=$(echo -en '\xe2\x96\x92') #▒ 8
Z9=$(echo -en '\xe2\x96\x93') #▓ 9
N1=$(echo -en '\xe2\x94\x80') #─ a
N2=$(echo -en '\xe2\x95\x92') #╒ b
N3=$(echo -en '\xe2\x95\x97') #╗ c
N4=$(echo -en '\xe2\x96\xb6') #▶d
N5=$(echo -en '\xe2\x94\xbc') #┼ e
N6=$(echo -en '\xe2\x94\xa4') #┤ f
N7=$(echo -en '\xe2\x95\xa1') #╡ g
Z11="$(tr -dc '123456789a' < /dev/urandom | head -c 1)" //Z11 to Z13 not
Z12="$(tr -dc '123456789a' < /dev/urandom | head -c 1)" // used here (see
Z13="$(tr -dc '123456789a' < /dev/urandom | head -c 1)" //link)

echo -en $(tr -dcs ' ;",15bdef' ' ' < /dev/urandom | head -c $(echo -en "$[$(tput cols) * $(tput lines)]") | sed -e "s/1/$(echo -en "\033[0;36m$Z1\033[0m")/g" -e "s/5/$(echo -en "\033[0;32m$Z5\033[0m")/g" -e "s/b/$(echo -en "\033[1;36m$N2\033[0m")/g" -e "s/d/$(echo -en "\033[1;36m$N4\033[0m")/g" -e "s/e/$(echo -en "\033[0;32m$N5\033[1;32m")/g" -e "s/f/$(echo -en "\033[0;36m$N7\033[1;32m")/g"); tput cup 1
                 ^set^+^chars^ to implement from pool - here 1,5,b,d,e,f... so_________________________^add the appropriate sed subprocessing units for implemented chars i.e. first one we replace "1" with the value of $Z1 and apply color at the same time, then all the chars move down the pipe to all required blocks - we selected to implement 6 chars here so we have 6 sed blocks. 

[N.B. To remove the blank space from the pattern, remove it from both sets: tr -dcs ';",15bdef' '']

PS1="\[\033[1;36m\] $(echo -en '\xe2\x96\x91')$(echo -en '\xe2\x96\x92')$(echo -en '\xe2\x96\x93')[\t]$(echo -en '\xe2\x96\x93')$(echo -en '\xe2\x96\x92')$(echo -en '\xe2\x96\x91') \[\033[7;36m\]$(echo -en '\xe2\x97\x98')$(echo -en '\xe2\x94\xbc')$(echo -en '\xe2\x94\x80')\W$(echo -en '\xe2\x94\x80')\[\033[0;36m\]$(echo -en '\xe2\x94\x80')$(echo -en '\xe2\x94\x80')$(echo -en '\xe2\x94\x80')@$(echo -en '\xe2\x96\xb6')\[\033[0;36m\]"

PROMPT_COMMAND="echo -en '\033[0;36m$(tr -dc '=' < /dev/urandom | head -c $(tput cols))\n\033[01;46m$(tr -dc '~' < /dev/urandom | head -c $(tput cols))\033[0;36m$(tr -dc '=' < /dev/urandom | head -c $(tput cols))'$(tput cuu 2)"

Ta implementacja nie renderuje już w wierszu, ale drukuje całą sekwencję w jednym ujęciu na końcu sedprzetwarzania. Pojawia się tylko przy logowaniu raz lub ogólnie po bashuruchomieniu. Oto jeden taki losowy wzór przy uruchomieniu (możemy zobaczyć dwa odcienie zieleni i dwa odcienie cyjanu):

wprowadź opis zdjęcia tutaj

Ekrany pokazują wynik w standardowym terminalu Linux i działa również w xterm. Użyłem niektórych z tych nowych znaków wzorcowych w monicie PS1, podczas gdy PROMPT_COMMAND zajmuje się tylko aktywną linią i jej dopełnieniem 2 linii, które używają znaków 1-bajtowych.

Wzorzec dobrze pasuje również do mojej obecnej dystrybucji, która wywołuje archbey.bashrc .:

wprowadź opis zdjęcia tutaj

Jest na Boże Narodzenie! Pozdrawiam ludzi :)

Społeczność
źródło
1
To nie jest ostateczna odpowiedź ani wdrożenie, ale to kamień milowy! ;-)
Może być również możliwe wykorzystanie siły biblioteki takiej jak aalib - patrz aafirena przykład aafire -driver curses -extended -gamma 1 -floyd_steinberg -random 5ciepłe wprowadzenie.
Nie przegap tej odpowiedzi, która dotyczy omawianego tutaj ograniczenia kodu Unicode zakodowanego w UTF !!
4

Terminal zarządza oprogramowaniem, które działa tak samo jak przeglądarka internetowa: interpretuje sekwencje znaków w celu ustawienia wyświetlania (patrz man terminfo ). Powłoka bash nie powie terminalowi, jak wypełnić pusty obszar ekranu.

Niektóre terminale mogą mieć obrazy jako tło, takie jak gterm, ale nie są tworzone przez powłokę.

Emmanuel
źródło
Zredagowałem Q, aby szybko wyjaśnić, do czego się odnosisz, a także inne istotne informacje z ukrytych komentarzy.