プロジェクト

全般

プロフィール

難読化シェル芸の世界 » 履歴 » バージョン 3

kanata, 2025/05/10 09:07

1 1 kanata
# 難読化シェル芸の世界
2
3 3 kanata
{{last_updated_at(a-painter-and-a-black-cat, 難読化シェル芸の世界)}}
4
5 1 kanata
{{rawhtml(<div class="iframely-embed"><div class="iframely-responsive" style="height: 140px; padding-bottom: 0;"><a href="https://www.amazon.co.jp/dp/4839969698/?" data-iframely-url="//cdn.iframe.ly/ruaI2tU?iframe=card-small"></a></div></div><script async src="//cdn.iframe.ly/embed.js" charset="utf-8"></script>)}}
6
7
難読化シェル芸の本を書きました。オンデマンド本なので、ほとんど書店に並びません~
8
amazonでポチっとお願いします。kindle版もあります。
9
https://amzn.to/2D0FDNm
10
11
マイナビBOOKSでも販売中です。たまにセールがあります。
12
https://book.mynavi.jp/ec/products/detail/id=103255
13
14
BookLiveでも電子書籍で
15
https://booklive.jp/product/index/title_id/611073/vol_no/001
16
17
{{toc}}
18
19
# 正誤表
20
21
マイナビBOOKS - 「難読化シェル芸の世界 -Bashとすてきな難読化」サポートサイト
22
https://book.mynavi.jp/supportsite/detail/9784839969691.html
23
24
# 補足
25
26
## 12ページ:ファイル名展開
27
28
本書では、当機能を「ファイル名展開」と表記しています。
29
bashのman pageの原文では"Pathname Expansion"、日本語訳でも"パス名展開"であり、正しくはこちらの名称で記載した方がより適切でした。
30
31
## 13ページ:${変数名/pattern/word}の説明
32
33
置換の仕様が複雑です。以下の通り整理しました。
34
35
| パターン                | 一致の仕様 | sedで同じ動作をさせる場合  |
36
|-------------------------|------------|----------------------------|
37
| ${変数名/pattern/word}  |  最長一致  | sed -e "s/pattern/word/"   |
38
| ${変数名//pattern/word} |  最長一致  | sed -e "s/pattern/word/g"  |
39
| ${変数名/#pattern/word} |  最長一致  | sed -e "s/\^pattern/word/" |
40
| ${変数名/%pattern/word} |  最長一致  | sed -e "s/pattern$/word/"  |
41
42
43
## 13ページ:${変数名:offset:length}の説明
44
45
offset、lengthが負の数の場合を補記します。
46
47
offsetですが、マイナスを指定した場合は文法として別のパラメータ展開になります。
48
49
```
50
51
# 指定した変数が空文字列の場合は右に指定した文字が入る
52
$ hoge=
53
$ echo ${hoge:-fuga}
54
fuga
55
```
56
57
lengthは、以下の通りです。
58
59
 * 省略した場合はオフセットから最後まで出力
60
 * マイナスを指定した場合は最後からマイナス分引いた位置までの長さになる
61
62
```
63
$ hoge=abcdefg
64
$ echo ${hoge:2}
65
cdefg
66
$ echo ${hoge:2:-2}
67
cde
68
```
69
70
71
72
73
## 13ページ:大文字小文字の変換の説明
74
75
本書では、大文字小文字の変換を${変数名\^}、${変数名\^\^}、${変数名,}、${変数名,,}と表現していました。正確には${変数名\^pattern}という形式になり、patternを省略した形となります。pattern を省略した場合、? を指定したものとして扱われ、 全ての文字にマッチします。
76
77
```
78
$ hoge=abc
79
$ echo ${hoge^}
80
Abc
81
$ echo ${hoge^^}
82
ABC
83
$ echo ${hoge^^b}
84
aBc
85
$ echo ${hoge^^bc} # 1文字しか指定できないようです
86
abc
87
```
88
89
## 14ページ:シェル変数について
90
91
シェル変数(原文では"Shell Variables")という単語はman pageでは別のニュアンスで使われています。
92
シェル変数、環境変数を別のものとして表現しているというより、シェル変数が環境変数を包含しているような表現になっています。
93
94
```
95
環境変数⊂シェル変数
96
```
97
98
本書においては、性質が異なる二種類の変数をそれぞれ「シェル変数」「環境変数」と定義(別々のものとして扱う)して説明しています。
99
100
## 39ページ:echoの代替
101
102
exprでも代替できます。
103
104
```
105
$ expr "Hello World"
106
Hello World
107
```
108
109
## 23ページ:foldによる文字の折返し
110
111
本書では、foldコマンドより折り返しをしていますが、foldコマンドはバイト単位で処理するため、"難読化シェル芸難"が16バイトにならない言語環境では上手く動作しませんでした。grepを利用することで言語環境の違いを考慮することなく処理することができます。
112
113
```
114
$ yes 難読化シェル芸|head -n8|tr -d '\n'|grep -oE '.{8}'
115
```
116
117
## 61ページ:Twitter用Unicodeゼロ幅スペースぶっ込みツール
118
119
実は、今のzwsは以下の制限があります。
120
せっかくなので、こういった入力のパターンも受け付けるように修正したい所です。
121
122
ヒアストリングによる入力を受け付けない
123
124
```
125
$ zws <<<string
126
```
127
128
ヒアドキュメントによる入力を受け付けない
129
130
```
131
$ zws <<EOS
132
string
133
EOS
134
```
135
136
修正方法を少し考えてみたいと思います(修正できたらこちらでお知らせします)
137
138
## 71ページ:算術式展開で数値を得る
139
bashのver5において、算術式展開を評価する仕様が変わったらしく、インクリメントと乗算を組み合わせた式が期待通りに動作しません。
140
141
以下の構文はbash ver5ではエラーになります。
142
143
```
144
$ # bash ver4
145
$ echo $((++z*++z---z)) # ++z * ++z - --z と解釈される
146
1
147
$ # bash ver5
148
$ echo $((++z*++z---z)) # エラーとなる
149
-bash: ++z*++z---z: --: assignment requires lvalue (エラーのあるトークンは "---z")
150
```
151
152
そのため、bash ver5環境において、本書の記号難読化シェル芸(ページ71)を動かすには、以下を置き換える必要があります。
153
154
変更前
155
156
```
157
$((z=z^z))                           #  0 自分自身でXORすると0になる。何回実行しても0。
158
$((z=z^z||++z))                      #  1 よくわからないが1になる。何回実行しても1。
159
$((++z*++z---z))                     #  4 変数zの初期値が1前提
160
$((++z+++z+--z))                     #  7 変数zの初期値が1前提
161
$((++z*++z*z))                       # 18 変数zの初期値が1前提
162
$((++z*++z*++z*z-z+++z))             # 19 変数zの初期値が0前提
163
$((++z*++z*++z---z+++z---z))         # 22 変数zの初期値が1前提
164
$((++z*++z*++z---z+++z---z+++z---z)) # 23 変数zの初期値が1前提
165
$((++z*++z*++z))                     # 24 変数zの初期値が1前提
166
$((++z*++z*++z---z+++z---z+++z))     # 26 変数zの初期値が1前提
167
```
168
169
変更後(bash ver4,ver5 両方で動作可能)
170
171
```
172
$((z=z^z))                           #  0 自分自身でXORすると0になる。何回実行しても0。
173
$((z=z^z||++z))                      #  1 よくわからないが1になる。何回実行しても1。
174
$((++z+--z+z))                       #  4 変数zの初期値が1前提
175
$((z+++z+z+z))                       #  7 変数zの初期値が1前提
176
$((++z*++z*z))                       # 18 変数zの初期値が1前提
177
$((++z*++z*z+z^z+z))                 # 19 変数zの初期値が0前提
178
$((++z*++z*z+z^z))                   # 22 変数zの初期値が1前提
179
$((++z*z*z*z+z^z+++z))               # 23 変数zの初期値が1前提
180
$((++z*++z*++z))                     # 24 変数zの初期値が1前提
181
$((++z*++z*++z*z-z*z*z---z-z))       # 26 変数zの初期値が1前提
182
```
183
184
## 74ページ:$_について
185
186
特殊変数 $_ ですが、以下のような条件においては代入が可能であることを補記しておきます。
187
確かに_=hogeのような代入は出来ませんが、
188
189
```
190
$ : 1
191
$ echo $[++_] $[_+=3] $_
192
2 5 5
193
```
194
195
のように、算術式評価で変更したり
196
197
```
198
$ : ""
199
$ echo ${_:=123} $_
200
123 123
201
```
202
203
のように、パラメタ展開による代入は可能です。
204
205
## 80ページ:${!#}の説明
206
この部分は明確に誤りであったため、訂正します。${!変数名}は、変数間接展開(indirect expansion)と呼ばれるものになります。結果的に動作は同じでしたが、$!とは無関係の機能です。
207
208
変数間接参照展開は、変数の中身を変数名として扱う機能であり、以下の動作になります。
209
210
```
211
$ fuga=aaa
212
$ hoge=fuga
213
$ echo ${!hoge}
214
aaa
215
$ eval echo '$'${hoge} # 変数間接参照展開と等価
216
aaa
217
```
218
219
改めて、${!#}の動作を解説すると、与えられた引数の数を表す$#に対して、変数間接展開をしていることになります。
220
この場合、$#は0となりますので、結果として、${!#}は${0}と等価となる訳です。
221
222
## 122ページ:英単語の先頭文字を大文字に変換する
223
224
sed単体でも可能であると、読者様よりアドバイスを頂きました。
225
226
```
227
$ echo foo bar buz|sed 's/\b\([a-z]\)/\U\1/g'
228
Foo Bar Buz
229
```
230
231
## 123ページ:標準入力を受け取る
232
233
testコマンドの-pを使う以下の方法ですが、パイプからの入力だけを判定しています。
234
ヒアドキュメントやヒアストリングなどは受け取らない点、ご留意ください。
235
236
```
237
$ echo |if [ -p /dev/stdin ];then echo "from pipe";fi
238
from pipe
239
```
240
241
## SpecialThanks
242
243
[くおん](https://twitter.com/qwertanus)さん
244
本書について、多くの指摘・アドバイスを頂きました。
245
246
# マイナビ連載(マナティ)
247
248
難読化シェル芸の世界 Bashとすてきな難読化①
249
https://book.mynavi.jp/manatee/detail/id=103580
250
251
難読化シェル芸の世界 Bashとすてきな難読化②
252
https://book.mynavi.jp/manatee/detail/id=103731
253
254
難読化シェル芸の世界 Bashとすてきな難読化③
255
https://book.mynavi.jp/manatee/detail/id=103808
256
257
難読化シェル芸の世界 Bashとすてきな難読化④
258
https://book.mynavi.jp/manatee/detail/id=103892
259
260
# 関連ネタ
261
262
* news#135
263
* news#134
264
* news#133
265
* news#124
266
* news#114
267
* news#95
268
269
# メディア
270
271
{{rawhtml(<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">フェア情報:6階上りエスカレータ前にて『マイナビ出版 プレミアムブックスフェア』を開催中。期間中、対象商品をお買い上げのお客様にマイナビ特製Tシャツをプレゼント。6階カウンター、または店員までお声掛けください。なおTシャツの枚数・サイズには限りがありますので、予めご了承ください。 <a href="https://t.co/eeypyVkiaO">pic.twitter.com/eeypyVkiaO</a></p>&mdash; ジュンク堂書店 池袋本店/PC書 (@junkudo_ike_pc) <a href="https://twitter.com/junkudo_ike_pc/status/1149878979857244160?ref_src=twsrc%5Etfw">July 13 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>)}}
272
273
{{rawhtml(<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">ほ、ほんとうに平積みされてた…! <a href="https://twitter.com/hashtag/%E9%9B%A3%E8%AA%AD%E5%8C%96%E3%82%B7%E3%82%A7%E3%83%AB%E8%8A%B8?src=hash&amp;ref_src=twsrc%5Etfw">#難読化シェル芸</a><br>ジュンク堂書店楽しい… <a href="https://t.co/lEUltN8WGL">pic.twitter.com/lEUltN8WGL</a></p>&mdash; kanata (@kanata201612) <a href="https://twitter.com/kanata201612/status/1152406535747719169?ref_src=twsrc%5Etfw">July 20 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>)}}
274
275
{{rawhtml(<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">頂きました!ありがとうございます!<a href="https://twitter.com/hashtag/seccamp?src=hash&amp;ref_src=twsrc%5Etfw">#seccamp</a> <a href="https://t.co/1FN11qMitX">pic.twitter.com/1FN11qMitX</a></p>&mdash; ぶうううん (@buuuuuuun3939) <a href="https://twitter.com/buuuuuuun3939/status/1162357892109832192?ref_src=twsrc%5Etfw">August 16, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>)}}