次ログ

次ログ

ゆるりと働いているSREの技術ブログのような何か。趣味の話も書く

シェル芸bot環境につぶやいてきたジョークシェル芸をひたすら書き連ねる(その2)

シェル芸botに垂れ流したシェル芸を自分が忘れないようにメモするだけの記事。 前回のに比べると今回はしょうもないものが多い(前回のもしょうもない)。

その2だけれど続けるかどうかはわからない。

シェル芸

5000兆円欲しい

5000兆円でなくてもいいけれど、時間に対して給与がより多いほうが良い。

{分,時}とかってのはBashのブレース展開という記法。 カンマで区切られた全ての組み合わせパターンを生成できる。

要はこういうこと。

$ echo {a,b,c}_{1,2,3}\\n
a_1
 a_2
 a_3
 b_1
 b_2
 b_3
 c_1
 c_2
 c_3

ブレース展開はシェル芸で結構多用する。文字数をかなり削れるケースがあるため。 sedと組み合わせてこんなふうに置換式を書いたりできる。 -esedの式を空白で区切らず隣接させないといけない。

$ echo 'abc-abc-abc' | sed -e's/'{a,b,b,c}'/0/'
000-a0c-abc

これは以下と等価。

$ echo 'abc-abc-abc' | sed -es/a/0/ -es/b/0/ -es/b/0/ -es/c/0/

溶け出すうんこ

ネタ系、不気味。 💩を一旦「うんこ」に置換して、「うんこ」の文字のいずれかにマッチすると💩に置換する。 ようは💩を💩💩💩に置換していることと結果的には同じ。

ojichatメール誤送信

GitHub - greymd/ojichat: おじさんがLINEやメールで送ってきそうな文を生成するfakerでそれっぽい文章を作っただけ。 fakerでは偽名とか住所とかそれっぽいものを作れる。

cat << EOS

EOS

はヒアドキュメントというもの。複数行のテキストを表現できる。 $()で間にシェルの実行結果を埋め込める。

ojichat文字化け

またojichat系。iconvで文字化けさせた文字と文字化けしていない元の文字をランダムにとりだして ところどころ文字化けしている文章を生成する。

pasteでは元の文章と文字化けした文章を2列のデータとして結合している。

$ paste -d "" <(元の文章を1列で表現するシェル) <(元の文章を1列で且つ文字化けさせるシェル)

iconv -c -f CP932 -t UTF-8で文字化けを意図的に起こしている。

普通のLinux環境だとデフォルトの文字エンコーディングはUTF8だけれど ここでは元の文字エンコーディングをあえてCP932として指定している。

なので、UTF8の文字をCP932として無理やりUTF8に変換している。-cでは文字の変換に失敗しても無視する。

$ n=$(shuf -e 1 2 -n 1); echo "$line" | sed -E 's@(.)(.)@'\\$n'@g'

ここでは変数nの1か2の値をセットし、sedの後方参照でどちらの文字を出力するかに指定している。 (.)(.)正規表現での文字のグルーピングの表現で、それぞれ任意の文字が1つずつ格納されている。 1文字目を取得するときはsedの置換式で\1を指定する、2文字目なら\2である。

なので、1/2の確率で文字化けした文字が取り出されるので、文字化けした文字と普通の文字を混ぜることができている。

でかい文字

textimgで文字をそのまま画像にして出力して ImageMagickでPGM画像に変換している。

PGMは数値を画像のピクセルと色に見立てて表現するテキスト形式の画像フォーマット。 色の数値部分のみ取り出して置換して任意の文字に置き換えるというアプローチをしている。

lolcatは色を付けるコマンド?よく知らない。最終的にまたtextimgで画像に変換して終了。

シャブキメ

ネタ系。ブレース展開の組み合わせとtrでの置換でテキストを表現。 短く書けたので満足。

元はこれ

btnmaker.me

色が移動

awkで1文字ずつ文字をエスケープシーケンスで囲って出力するだけ。 テキストの折り返しには tee >(tac) を使用。

teeはパイプ元の入力を標準出力に出しながらファイルにも出力できるコマンド。 サーバ作業のときにはよくお世話になる。 今回はファイルではなくコマンドのtacに渡している。 >(コマンド)でコマンドに渡せる。

tacは入力ストリームを行で逆順に出力する。catの逆なのでtac。

難読化16進数date

dateコマンドを難読化して実行。 bashでは$'\U16進数'で16進数をそのコードポイントに該当する文字に変換して出力する。 たとえば あ を16進数で出力するには $'\U3042' と書く。

あとは数値の部分をどうやってわかりづらくするか、に$$を使用した。 $$は難読化シェル芸で頻出の、プロセスIDを取得する特殊変数。 プロセスIDはコマンドの実行ごとに変化するが、$(($$/$$))としたら同じプロセスIDで割ってるので 1が得られる。あとはそれを組み合わせてほしい値を取り出してる。

__=(.{,,,}{,,,}{,,,});___=(.{,,,}{,,});

の部分は僕もなんでこんなこと書いたのが思い出せなかった。 echo ${#__[@]} してみたら64が得られたので、多分この辺の数値が欲しかったんだと思う。 ${#変数名[@]}とやると配列変数の長さを取得できる。前述のでは、.文字をブレース展開で複製して 64個の配列要素にしてるっぽい(書いた本人が忘れてる)。

ファイル名アスキーアート

toiletコマンドの結果をファイル名に使用するというアプローチ。 元はwhileでループしてたけれど、もっとスマートに書きたくていろんなテクを使ってみた。

eval

evalはbashのコマンド列を評価する。ここにブレース展開とセミコロンを入れることで、 複数のコマンドの実行を短く実現している。

eval 'toilet '{ほ,ん,ば,ん}';'

このコマンドは以下のコマンドと等価である。

(toilet ほ; toilet ん; toilet ば; toilet ん;)

単純にtoiletをセミコロンで区切って実行した場合だと、それぞれのコマンドの実行結果をパイプ先に渡せないが evalとブレース展開で実行するシェルはサブシェルとして1つにラッピングされてるみたい。 今回みたいに、セミコロンで区切った複数のコマンドの実行結果を全てパイプ先に渡せている。

ようはこういうこと。

toilet ほ; toilet ん; toilet ば; toilet ん; | nl # 構文エラー
(toilet ほ; toilet ん; toilet ば; toilet ん;) # OK
eval 'toilet '{ほ,ん,ば,ん}';' | nl # OK

lolcat

特に言うことはない。色を付ける

nl

普段nlコマンドなんて全く使わないけれど、数値出力のフォーマット指定と区切り文字の指定ができることを知った。 これで3桁、0埋め、区切り文字にアンダースコアという指定になる。

nl -w3 -nrz -s__

sed

最後、テキスト全体をtouchのコマンド文字列に置換してeでそのままシェルのコマンドとして実行。

sed -E "s/.*/touch '\/__&'/ge"

ようはこんな感じの文字列に置換している。

touch '/__001__ほげほげ〜〜〜'
touch '/__002__ほげほげ〜〜〜'
touch '/__003__ほげほげ〜〜〜'

中央寄せアニメーション

ネタ系。特に書くことがない。普通のgrep awk。出力している文章は、最近僕がハマっている 「クトゥルフ神話TRPG」の書籍に登場する一文。

嘔吐

ネタ系。echoをgrep awkしてキングウンコに連結してるだけ。特に書くことない。

ホクホクのイモ

いかに触発されてやった。

qiita.com

ホクイモ からランダムで2文字取り出すのを2回実行し、実行結果を正規表現の後方参照で取り出して出力した。

PowerWord

ネタ系。こちらも触発された系。 自前のalignコマンドでテキストを左右中央寄せして 任意の文字数の位置まで正規表現で置換してエスケープシーケンスをつけただけ。

Windows XP ?

Windows XPの画像を再現したかったけれど、再現度が低くてよくわからない。

横切るウンコ

seqの値をパディングの回数として使用してsedでテキストの先頭に埋め込んでいるだけ。 最後に tee tacでひっくり返す。

まとめ

画像系、アニメーション系が多かった。 textimgを自作してから画像系シェル芸をよくやるようになった。 最近はネタ切れになってしまった。その3記事は書かないような気がする。