プロジェクト

全般

プロフィール

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

kanata, 2025/04/13 09:50

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