こんにちは。株式会社フィックスポイントのよしだです。
今回は、エンジニアの tennashiさんより、 echo コマンドの使用方法について勉強会にて発表がありました。
echo と言うと、画面に文字列を出すためのもの、というイメージが強い方もいらっしゃるかもしれません。
しかし、echo には文字列を出現させるに留まらない機能がありますので、ぜひ本記事を機に活用してみてください。
echoって?
本題に入る前に、echo をよくご存知ない方のために概要を説明します。
echo とは、ざっくり言うと引数の文字列を出力するためのコマンドです。
下の例を見ると分かるように、入力された文字列 hoge をそのまま標準出力に表示しています。
$ echo "hoge"
hoge
冒頭でも触れたように、この echo コマンドは"そのまま" 表示するだけではなく、他にも様々な効果を付けることが可能です。
エスケープシーケンスを使用した表現
エスケープシーケンスというものを使用すると、ただ表示する以外のことも可能になります。
いくつかの例を基に、見ていきましょう。
1.改行
まずはこちらを例として説明します。
$ echo -e "hoge\nfuga"
hoge
fuga
そのまま見て取れるように、hoge\nfuga ではなく hoge と fuga が改行されて表示されています。
上記を説明するには、2つの要素に注目する必要があります。
1点目として、コマンドの中に -e というオプションが入っているのが分かりますでしょうか。
この -e が一つのポイントとなります。
もし、上記コマンドから -e を抜くと、このようになります。
$ echo "hoge\nfuga"
hoge\nfuga
一番最初の説明のように、改行ではなく hoge\nfuga という文字列がそのまま表示されています。
つまり、この -e というオプションの有無が、改行ができるかという部分に関わってきます。
続いて2点目、もうお気付きかとは思いますが、hoge\nfuga の中に \n という文字が入っています。
これこそが、本項でのキーとなるエスケープシーケンスと呼ばれるものです。
\n のような、 \ から始まる一連の(特定)文字列(=エスケープシーケンス)を出力すると、画面描写を操作できるようになります。
今回の \n は改行する、ということを意味しています。hoge\nfuga は hoge \n fuga と解釈された結果、hoge と fuga が改行されて表示されたという訳です。
そして、先程の -e オプションとは、このエスケープシーケンスをただの文字列ではなく、エスケープシーケンスとして処理しますよ、というためのものです。
そのため、 -e がカットされていると hoge\nfuga がそのまま文字列として表示されてしまうのです。

2.文字色の変更
さて、エスケープシーケンスを使用すれば、改行以外にも様々なことが可能です。
続いては、少し複雑な文字色の変更について紹介します。
$ echo -e "\e[31mhoge\e[0mfuga"
hogefuga
上記はコードブロックなので正しく表現できていませんが、実際には hogefuga のように表示されます。
今回の場合、描画されているのは hoge と fuga なのでそこを除いた部分がエスケープシーケンスです。*1
すると、 \e[31m と \e[0m というエスケープシーケンスが出てくるのではないでしょうか。
改行の際と異なり、大分長くなったことが見て取れます。
今回のような "長い" エスケープシーケンスには、多様なカテゴリが存在しています。
これらを読むときには、 "どのカテゴリの" "何番" なのか(さらにパラメータがある場合もあります)、と分解して解釈すると理解しやすいかと思います。

それでは、今回も分解していきましょう。
今回の場合は、 \e[*m が文字装飾のカテゴリを、31 や 0 が実際の処理内容を示しており、m はシーケンス終端の目印にもなっています。*2
実際の処理である 31 と 0 に着目してみます。
まず 31 では、 3 が文字の色(foreground color) を変更することを、1 が色を赤にすることを示しています。
つまり、\e[31mhoge は、「 hoge という文字について、文字色を赤にして表示してください」というコマンドになります。
ちなみに他にもご紹介すると、 3 のところを 4 にすると背景色(background color) を変更するという意味に変わります。また、1 を 2 にすると緑色を指定したことに変わります。
続いて 0 では、ここまで指定してきた描画の変更を全部リセットする、という意味を示しています。
そのため、 \e[0mfuga では、「 fuga という文字について、前まであった指定(文字色を赤にする)をやめて表示してください」というコマンドになります。
3.複雑なエスケープシーケンス
先にちらっと記載しましたが、パラメータがある場合についても見てみましょう。
$ echo -e "\e[38;2;255;0;0mhoge\e[0mfuga"
hogefuga
これも先程と同様に hogefuga のように表示されるかと思います。
さっきと同じじゃない…?という方もいらっしゃるかと思いますが、今回は "真っ赤" というパラメータを指定した状態です。
今回注目すべきは、 \e[38;2;255;0;0m です。
\e[*m の部分は前と同じ意味ですので、中の 38;2;255;0;0 を分解していきましょう。
頭の 3 も前項と同じく文字の色を変更するという意味です。
次の 8 が今回のポイントとなります。
8 のコマンドについて詳細な話に入る前に、端末上で表示できる色のパレットについて説明します。
パレットにはいくつか種類があり、下記の通り分かれています。
-
- 8色(3bit): 黒赤緑黄青マゼンタシアン白
- 16色(4bit): 上記8色各々の明度を上げたものを加える
- 256色(8bit): 中間色を加えた
- TrueColor(24bit): いわゆる #RRGGBB で表現できる色
3 のあとに続く数字が 0 - 7 の場合は、3bit color を指定したものと解釈され、各数字に当てはまる色が指定されます。
4bit color はこれまでと異なり、頭を 9 にしたあと 0 - 7 を入れて 3bit color と同様に指定します。
3 のあとに 8 が続くと 8bit または 24bit の拡張を利用していると解釈され、どちらであるかは更に続くパラメータで指定されます。
今回は、 8 が指定されているので 8bit または 24bit のパラメータ指定が続くということになります。
エスケープシーケンスのパラメータは ; または : を挟むことで指定できます。
どちらに対応しているかは利用している端末に依るので、実際叩いてみて確認してみてください。*3
ここまでで、 \e[38;2;255;0;0m を解釈するための道具はそろったので、内容を紐解いて行きましょう。
\e[*m: カテゴリ指定3: 文字色変更8: 8bit or 24bit 拡張を利用2: 24bit 拡張を利用(8bit 拡張の場合は5になる)255: R 値0: G 値0: G 値
以上のことから、 #ff0000 で文字が表示されたという訳です。

参加者の反応
今回の発表を聞いた参加者の反応です。
この発表をきっかけに興味が出てきた人もいるようですね!
思い思いの感想をSlackに書き込んでいます😊

最後に
今回は、echo コマンドの様々な活用方法についてご紹介しました。
もっと複雑な内容も勉強会では扱いましたので、続いての記事に記載する予定です。
echo コマンドに興味のでた方は是非ご覧になってみてください!
⇛echo コマンド応用編はこちら。
株式会社フィックスポイントでは、一緒に働いてくれるメンバーを募集しています!
詳細は、こちらをご覧ください。