コンテキストと質問
端末とシェル環境を色付けする方法はたくさんあります。などの個別のコマンドの出力ls
とはgrep
、また、色付けすることができます。直接関連するわけではありませんが、コンソールでメディアを再生するという概念は興味深いものですが、これはウィンドウシステム上のフレームワーク(ライブラリ)に依存しているようです。次の質問は、bash
シェルとそのLinuxターミナルフレームワークでの実装とその基盤のみを対象としています。
2D ゲームのシーンのASCII「レンダリング」の次のモンタージュを検討してください。
これらは、ランダムに生成されたシーンではありません。私が選択したすべてのセグメントは、実際には、ASCII文字を使用してこのようなオブジェクトを表現するゲームの「草地」地形(樹木、低木、低木、花、草など)を表します。最後の4シーンは、ユーザーが作成したタイルセットを示しています。タイルセットは、基本的に色仕様のASCII文字のリマップです(詳細は簡単です。これは、視覚とパターン")。
モンタージュ共有のこれらのシーンの一般的な機能は次のとおりです。
- 最大で5〜6個の異なるASCII文字(カンマ、引用符、その他いくつか)
- 使用される2-4色
- キャラクターのために
- 場合によってはキャラクターの背景について-最後の例は、パターンを作成するためのキャラクターをほとんどまたはまったく持たないカラーシェードの使用、つまりカラーモザイクの使用を示すためのものです。
現在VMにあるのはArch Linuxで、質問はディストリビューション固有のものではありませんが、ファイルをカスタマイズするためのドキュメントを調べました/etc/bash.bashrc
。多くの説明がプロンプトの外観と一般的にすべての前景要素の構成に進むことがわかります。背景の設定に関する情報はほとんどありませんが、通常これらの設定やヒントなどの単色の場合を除きます。
# 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
コンソールを使用するときに入力しなかった空/空白/背景の「スペース」、つまり「何でできているのか」を概念的に把握していません。いわば。特に、プロンプトに表示されず、エコーされるコマンドをラップするもの。アクティブな行で発生することに関してbash
、「行指向」の方法で動作し、一部の操作がアクティブな行のクリアをトリガーすることを示すことができfor i in $(seq 1 $(expr $(tput lines) \* $(tput cols))); do echo -n M; done; tput cup 15 1
ます(、プロンプトでcharを入力し、バックスペース-貢献者)-その範囲はCLIごとに異なる場合があります(zshなど)。私のような何かを追加する場合さらに、それはそうです\[\033[44m\]
で私のPS1ラインにbash.bashrc
そう明らかに私が知っていること-私はbashのをリロードした後、青色の背景を取得し、いくつかのバックグラウンドに関する限り、出力の外観をここで活用します。
しかし、bashは、TTYサブシステムという形で他の機能に依存して画面に情報を表示するソフトウェアであることも知っています。これは、そこから、カーネル内のVTコンポーネントに移行します。pstree -Ap
Archショーにsystemd
リンクされてからにリンクさlogin
れbash
ます。
アーチのLinuxディストリビューションは、依存するagetty
TTYサービスのために。シンプルecho $TERM
は、使用中の端末のタイプ(ここではDE以外の「linux」)を生成し、infocmp[-d spec1 spec2]
パラメータなしのコマンドは、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,
現状では、ターミナルフレームワークから多くの機能を活用できます。PS1変数を設定してプロンプトをカスタマイズする限り、基本的にはbash.bashrc構成ファイルで公開される機能です。制御およびエスケープシーケンスは、基本的に、端末情報データベースに記述されているカーソルの移動やその他の機能を含む機能を提供するために、端末で表示される文字の流れを中断するために使用されます。これらの関数の多くは、よく知られているESC[
(または\ 33)Control Sequence Introducerを使用して渡されます(ここおよびここでのシーケンスと、いくつかの例)。さらに、使用することも可能ですtput
CLIで直接ユーティリティを使用して、一部の端末プロパティを変更します。たとえばtput setab 4
、青色の背景にbash echoコマンドがあります。
strace bash
エスケープシーケンスと動作の両方を確認できる場合:
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
これは、端末の空のスペース/背景色をランダムな(しかしきれいな)ASCII文字セットに置き換えることができるという質問のコンテキストを提供しますか?しかし、機能を実装する方法や、私が端末で探しているものについてはわかりません。
そのため、これが可能な場合の最終結果がどのようになるかを示す例として、粗雑なモックアップを作成しました(真剣ではありません:)。
基本的に、端末のすべての「空のスペース」はパターンで満たされます(ここでは、上からの画像の1つを「タイル」にしますが、実際の実装では、個々の「空白」を指定されるモンタージュから文書化された5-6文字と機能)。アクティブなコマンドラインには異なるパターン、つまり波状の「水」がありますが、そのラインは青に落ち着きます。これが想像されたように、コマンドはアクティブな行に入力されると「水」を「消去」します。もちろん、文字のパターンがCLIによって解釈されないという制約があります。
bash
端末フレームワーク内または端末フレームワーク内で公開されている設定、または文字のセットと色の制御を使用して端末のbashの出力を変更して背景にややランダムなパターンを生成できるスクリプトがあります(これは私が上に示したものに似ています)?または、ttyの背景として完全なパターンイメージを提供しようとするようなものに単純に落ち着く必要がありますか?
実装
0.1-PatternOTDバージョン(ログイン時のワンショット取引)
.bashrcファイルに追加した次の式は、調査した概念の一部をまとめたもので、標準の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
観察
- それは明らかに単なるコマンドなので、永続的ではありません。つまり、コマンドが入力されるとスクロールします
- 文字の選択を個別にランダム化しないことを選択
head -c 1
しました。つまり 、tput cols
最初に行を乗算すると、引用された選択から個々のランダムな文字が出力されます-遅すぎるためです。random
(tput cols)long integerを生成するとは思いませんが、それでも高速です。確かにこれはすべて非常に無駄ですが、動作します。 - 説明したように、各文字を個別にレンダリング/処理するのは遅すぎるため、文字ごとに色や効果をランダム化したり、緑以外はランダム化しませんでした。再:フレームバッファ?
- CLIによって解釈されないという意味で、パターンがCLIの使用を妨げないことを確認できてうれしいです!(説明できなかったのに)
- 水が速すぎます!;-)
0.2-PROMPT_COMMANDハックジョブ
変数PROMPT_COMMANDの値は、Bashが各プライマリプロンプトを出力する直前に調べられます。通常、変数を使用して、ディスプレイなどから要素を処理できるスクリプトを呼び出すことを知っていますが、.bashrcファイルで直接これを実行しようとしています。当初、私はいくつかの位置認識、つまり実行前にカーソルがある場所を実装できると思っていました(したがって、どこでも画面上のものをレンダリングtput
して、前の位置に戻って、このようなものを使用して位置を抽出できます:
stty -echo; echo -n $'\e[6n'; read -d R x; stty echo; echo ${x#??} //value is in x;x format so...
値をにパイプしますcut -f1 -d";"
。私はCLIでこれを行うことができますが、PS1 / P_C変数の要素のシーケンス内でこの作業を行うことは現時点では手の届かないところにあり、PROMPT_COMMANDに入れられたコマンドがキャリッジリターンごとに評価されることはなく、むしろ毎回実行されるにもかかわらず、一度だけ(?)(以下の所見を参照)。
したがって、私ができる最善の方法は、初期シーケンスを引き継ぎ、PROMPT_COMMANDと.bashrcのPS1変数の定義の両方にいくつかのコマンドを追加することです。そのようです:
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
要約すると、P_Cを使用して永続的な視覚パターンを実装しようとしています。つまり、2行追加されます。残念ながら、「水」トリックを繰り返しながらこの両方のパターンを作成することはできません。つまり、アクティブなラインを青色にします(背景色を変更し、クリアラインを実行し、背景を黒に戻します)。これを一緒に再生する方法を示すために画像をまとめました。
観察
- 行でバックスペースを使用すると、依然として行の明確な動作がトリガーされ、青が消えます
- Enterキーを押すたびに、新しいアクティブな行の前に2行のパターンがあります
- もちろん、余分な行があるにもかかわらずさらに下にあるように、コマンドのようなパターンをラップしていません。
ls
- ここでP_Cを呼び出すと、/ dev / urandomのランダム性はそれほどランダムではないようです。この画像は2つの画像で構成されていますが、余分な2行のパターンは常に同じです。つまり、Enterキーを押すたびにランダムは生成されず、2行ごとに1回だけ-おそらく最初の行のみtime .bashrcはによって読み取られ
bash
ます。 - PS1変数の内容は、
$(echo -en '\n') $(tput setab 4)
$(tput ...)の直前の真ん中のスペースで始まります。これが機能するには、そこになければなりません。そうしないと、青い線がプロンプトの前ではなくプロンプトの上部に表示され、解決できません。そして、このハックはその名前を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\]"
PROMPT_COMMANDで行われるのは、プロンプトが生成される前に毎回3行のパターンが印刷されることです。これらの3セットのパターンは0.2で説明した制約内で個別に生成されます。次に、2行上に移動し(を使用tput cuu 2
)、PS1に従って中央の行にプロンプトが生成されます。ターミナルにログインしたときに一度だけ実行される.bashrc loadの全画面パターン用のコマンドの初期セットがまだあります。これで、アクティブな行の周りにいくつかのパディングがあり、戻りのキャリッジがあるときに常に繰り返される独自の青いパターンがあります。PS1変数とP_Cの内容はサニタイズされました。long内に埋め込まれたエスケープシーケンスとカラーコーディングの構文echo
シーケンスには注意が必要です。エラーが端末の奇妙な動作につながる互いに上書きする行、左マージンから離れて表示されるプロンプト、または意図せずに処理されたものへの異常な出力を含む。私がやっていることには条件があります。PS1変数の内部に余分なスペースが必要で、Linux端末とlxtermとのセットアップの視覚的な違いに対処します(Arch Bang)。余分なスペースがないと、Linuxターミナルは、何らかの理由でプロンプトの最初の文字を最後の行の最後に出力します(もちろん、これはデフォルトの動作ではなく、私が行うことです)。また、パフォーマンスを向上させるために長い文字列を生成することが早くから決定されていたため、引用符で囲まれた文字セットにランダム効果(太字、逆など)を生成する方法がわかりません。
ターミナルが開いたときの初期パターン
clear
プロンプトで連続してEnterキーを押した後の動作
観察
- 一括で行うことを超えてパターンの色付けを実装するために、再設計または修正する必要があります
- さらに先へ進むには、すべてをスクリプトに入れるか、より高度な抽象化を活用する必要があると感じ始めます。しかし、端末の機能はエンドユーザーにとって非常に有効です(「ロゴ」を思い出します)!