bash-記号と数字で「Hello World」

#はじめに
bashで数字と記号のみを使って「Hello World」を出力するだけの記事

##bashのバージョン
実行した際のbashのバージョンは以下

```
$ bash --version
GNU bash, version 4.2.46(2)-release (x86_64-redhat-linux-gnu)
Copyright (C) 2011 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
〜以下略〜
```

#コマンド
コマンドは以下。

`__=$(__=“$(+ 2>&1)”;__=${__:13:3};${__} 2>&1);___=“$(/# 2>&1)”;____=${__:1:1}${___:22:1}${__:10:1}${__:10:1}${__:18:2}${__:0:1}${___:24:2}${__:10:1}${__:17:1};____=“${____^}”;___=${___:30:2}${___:4:1}${___:12:1};${___} ${____}`

これを実行すると、「Hello World」が表示される。

```
$ __=$(__=“$(+ 2>&1)”;__=${__:13:3};${__} 2>&1);___=“$(/# 2>&1)”;____=${__:1:1}${___:22:1}${__:10:1}${__:10:1}${__:18:2}${__:0:1}${___:24:2}${__:10:1}${__:17:1};____=“${____^}”;___=${___:30:2}${___:4:1}${___:12:1};${___} ${____}
Hello World
```

#解説
上記コマンドは、セミコロンを区切りとして分けることができる。
以下、セミコロンで分解して解説する。

①　`__=$(__=“$(+ 2>&1)”;__=${__:13:3};${__} 2>&1)`
②　`___=“$(/# 2>&1)”`
③　`____=${__:1:1}${___:22:1}${__:10:1}${__:10:1}${__:18:2}${__:0:1}${___:24:2}${__:10:1}${__:17:1}`
④　`____=“${____^}”`
⑤　`___=${___:30:2}${___:4:1}${___:12:1}`
⑥ `${___} ${____}`

##①　`__=$(__=“$(+ 2>&1)”;__=${__:13:3};${__} 2>&1)`
`__`はアンダーバーを二つ並べたもので、ここでは変数名として利用している。

`__="$(+ 2>&1)"`の部分は、以下のように`+`とだけ打った時に出てくるエラーメッセージを、`__`に代入している。

```
$ +
-bash: +: command not found
```

`__=${__:13:3}`では、変数`__`の13文字目からの3文字を切り取って、変数`__`に代入する処理である。
上記エラーメッセージの13文字目から3文字を切り取ると、「man」という文字が得られる。
そして、`${__}`の部分で、「man」という文字の入った変数`__`を展開している。

つまり、`__=“$(+ 2>&1)”;__=${__:13:3};${__}`を実行すると、bashに対して「man」というコマンド名が渡され、`man`コマンドが実行される。
しかし、このコマンドは引数を取る必要があるため、最終的にはこのようになる。

```
$ __=“$(+ 2>&1)”;__=${__:13:3};${__}  　　//manコマンドが実行される
What manual page do you want?　　　　　　　//引数がないのでエラーになる
```

よって、`__=$(__=“$(+ 2>&1)”;__=${__:13:3};${__} 2>&1)`は、`man`コマンドの
「What manual page do you want?」というエラー文を変数`__`に入れる処理となる。

##②　`___=“$(/# 2>&1)”`
`___`はアンダーバーを三つ並べたもので、やはり変数名である。

ここの処理は、`/#`と打った時に出る以下のエラーメッセージを、変数`___`に代入するというものになる。

```
$ /#
-bash: /#: No such file or directory
```

つまり、この処理で`___`には「-bash: /#: No such file or directory」という文が代入される。

##③　`____=${__:1:1}${___:22:1}${__:10:1}${__:10:1}${__:18:2}${__:0:1}${___:24:2}${__:10:1}${__:17:1}`
`____`はアンダーバーを四つ並べたもので、変数名である。

①と②で見たように、変数`__`と`___`は今、以下のようになっている。
`__`：What manual page do you want?
`___`：-bash: /#: No such file or directory

ここでは、これらの変数の文字を部分的に切り取って繋げていくということをただひたすらに行なっている。
これを実行したあと、`____`はこのようになる。
`____`：hello World

##④　`____=“${____^}”`
③で`____`には「hello World」という文字が入った。
bashで、`${変数名^}`のようにすると、変数名に入った先頭文字が大文字になる。

```
$ echo ${____}
hello World
$ echo ${____^}
Hello World
```

この処理によって、`____`には、「Hello World」の文言が入ることになる。

##⑤　`___=${___:30:2}${___:4:1}${___:12:1}`
これまでの処理で、`___`（アンダーバー三つ）は以下のようになっていた。
`___`：-bash: /#: No such file or directory

ここでは、上記文章から文字を切り取って繋げることで「echo」という語を作成し、`___`に代入している。

##⑥ `${___} ${____}`
最後のこの処理では、`___`（アンダーバー三つ）と`____`（アンダーバー四つ）の変数を展開している。
これらの変数の中身はこのようになっている。
`___`：「echo」
`____`：「Hello World」

つまり、`${___} ${____}`で`echo Hello World`というコマンドが実行されることになる。

#最後に
一番苦労したのは「w」という語を含んだエラーメッセージを探すところで、
`man`コマンドのエラーメッセージを発見した時は思わずガッツポーズが。

もっとうまい方法があるかもしれないので、探索したい次第。
数字も全部記号に置き換えるとか。。。

bashのバージョンによってはエラーメッセージの内容が異なる場合があるので、実行を試してみる場合にはご注意を。