Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
シェル芸のせかい / the Shellgei World
Search
Ryoto Saito
March 09, 2020
Programming
1.9k
2
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
シェル芸のせかい / the Shellgei World
Ryoto Saito
March 09, 2020
More Decks by Ryoto Saito
See All by Ryoto Saito
コンテナ上シェル悪用の話とPure Bashでcurlが作れた話
ryotosaito
2
710
CTFで学ぶPHPセキュリティ
ryotosaito
3
4.4k
Other Decks in Programming
See All in Programming
スマートフォンでモールス信号を送受信する 〜スマートフォンのLEDとカメラで作る光通信の設計と実装〜
atsuki_seo
0
230
残高管理から台帳サービスへの進化
artoy
0
140
WebRTC映像をAirPlayに対応させる挑戦.pdf
monolithic_adam
0
340
R8 の設定見直しでアプリサイズ削減
andpad
0
150
速く作れる。その次は、速く確かめられる開発へ 〜AIネイティブ開発を支える、Shift Down〜 / Can build fast. Next, moving to development where we can verify fast.
rkaga
8
5.5k
20260914 AIエージェント時代のPlatform Engineering LLM基盤とプロダクトの責務境界線
kanfab1
7
2.4k
Findy - エンジニア向け会社紹介/Findy Company Deck
findyinc
6
400k
SREの越境 / SRE Collaboration
y0hgi
2
300
contenteditable と日本語入力に向き合う
colorful12
0
120
Agents on Rails - Rails at Scale 2026
irinanazarova
0
330
Security issues being discussed on Web Platforms
petamoriken
0
1.4k
Jetpack Compose Mechanisms
skydoves
2
400
Featured
See All Featured
Exploring anti-patterns in Rails
aemeredith
4
520
Claude Code どこまでも/ Claude Code Everywhere
nwiizo
68
58k
Optimising Largest Contentful Paint
csswizardry
37
4k
Statistics for Hackers
jakevdp
799
230k
個人開発の失敗を避けるイケてる考え方 / tips for indie hackers
panda_program
123
22k
4 Signs Your Business is Dying
shpigford
187
23k
The B2B funnel & how to create a winning content strategy
katarinadahlin
PRO
1
550
The SEO Collaboration Effect
kristinabergwall1
1
590
Visualization
eitanlees
153
17k
技術選定の審美眼(2025年版) / Understanding the Spiral of Technologies 2025 edition
twada
PRO
120
120k
Fashionably flexible responsive web design (full day workshop)
malarkey
409
67k
Beyond borders and beyond the search box: How to win the global "messy middle" with AI-driven SEO
davidcarrasco
3
270
Transcript
シェル芸のせかい Ryoto (@systemctl_ryoto) 2020/03/09 Uedalab Meetup 1
こんにちは 今日はシェル芸のお話をします $ echo こんにちは $ echo すましを話おの芸ルェシは日今 | rev
2
$ w3m https://ja.wikipedia.org/wiki/シェル 芸 | grep ^シェル芸 -A 5 シェル芸[編集]
シェル芸とは、主にUNIX系オペレーティングシステムにおいて「マ ウスも使わず、ソースコードも残さず、GUIツールを立ち上げる間 もなく、あらゆる調査・計算・テキスト処理を CLI端末へのコマンド 入力一撃で終わらせること」(USP友の会会長・上田隆一による定 義^[9])である。この技術を持つ人物を指すシェル芸人という呼び 方も存在する^[10]。 3
シェル芸モチベーション • コマンド実行を効率化する • シェルの機能を最大限利用する • やりたい動作を素早く実現する • とっさの時のサーバトラシュー力が向上する •
GUIよりCLIの方が軽量、ソフトウェアも多い[要出典] 4
シェル芸とその基礎:標準入出力(stdio) 5
シェル芸を始める前に:標準入出力 • 入出力の抽象 • 標準入力(0)、標準出力(1)、標準エラー出力(2) • ファイルディスクリプタ番号は固定 • デフォルトはターミナル(tty)にバインドされている •
リダイレクト(<, >, <<, >>, etc.)によってファイルなどへ変更可 能 シェル芸とその基礎:標準入出力 (stdio) 6
$ echo terminal >$(tty) $ echo stdout >/dev/stdout terminal #
ターミナルへ直接出力 stdout # 標準出力へ出力(=何も指定しないのと一緒) 別の画面のttyに向けて echo hello >/dev/tty?? すると…? program /dev/tty?? /dev/stdout シェル芸とその基礎:標準入出力 (stdio) 7
$ echo うっしっし | cowsay # pipe “|” は前のプロセスのstdoutと後のstdinをつなげる #
これで立派なシェル芸人 _________________ < うっしっし > ----------------- \ ^__^ \ (oo)\_______ (__)\ )\/\ ||----w | || || pipe stdout echo stdin cowsay シェル芸とその基礎:標準入出力 (stdio) 8
シェル芸の沼にハマると • シェルでCMSを作って運用し始める https://github.com/ryuichiueda/bashcms2 • シェルでHTTPサーバを作り始める https://github.com/ryotosaito/shttpd • 少ない記号種でdateを実行するゴルフ?が始まる https://twitter.com/minyoruminyon/status/1152161173158055936
• シェル芸をTwitterに投下できるbotを作る https://github.com/theoremoon/ShellgeiBot • VUIでシェル芸をしたくなった結果呪文詠唱を始める https://speakerdeck.com/amanoese/vuidesieruyun-woshi-xing-dekiruyounisitemita 9 シェル芸とその基礎:標準入出力 (stdio)
$ echo fd1 >/dev/fd/1 $ echo alias >&1 fd1 #
ファイルディスクリプタ1 (= stdout) に出力 alias # >&1 は >/dev/fd/1のエイリアス まとめ:標準出力の表し方 • /dev/stdout • /dev/fd/1 • >&1 シェル芸とその基礎:標準入出力 (stdio) 10
$ echo stderr >/dev/stderr $ { echo error >&2; }
2>error.txt stderr # 標準エラー出力 → ttyに出力 # “error” を標準エラーに出力 → さらに error.txt に転送 # 標準出力も標準エラーもデフォルトはttyにバインド シェル芸とその基礎:標準入出力 (stdio) 11 program /dev/tty?? /dev/stdout /dev/stderr /dev/tty?? error.txt
$ man life 2>&1 | cowsay $ man life |&
cowsay 標準エラー出力をpipeしたい場合は、 • プロセス中で標準出力にリダイレクトする • 標準エラー出力も一緒にpipeする ’|&’ を使う __________________________ < No manual entry for life > -------------------------- \ ^__^ \ (oo)\_______ (__)\ )\/\ ||----w | || || シェル芸とその基礎:標準入出力 (stdio) 12
シェル芸の基礎:シェル機能 13
コマンド出力をコマンド文字列として認識する Command substitution $ docker rm $(docker ps -aq) #
dockerのコンテナを全て削除する # docker ps -aqはコンテナIDをリストする # 展開対象は標準出力(stderrはttyに垂れ流される) シェル芸の基礎:シェル機能 14
$ paste <(seq 1 3) <(seq 4 6) 1 4
2 5 3 6 # equivalent to # seq 1 3 >13.txt; seq 4 6 >46.txt; paste 13.txt 46.txt $ echo <(seq 1 4) <(seq 4 6) /dev/fd/63 /dev/fd/62 コマンド出力をファイルとして認識する Process Substitution シェル芸の基礎:シェル機能 15
その他Bashの有用な機能 • /dev/tcp/host/port でネットワークリダイレクト ◦ exec 3<>/dev/tcp/localhost/80 ◦ echo -e
"GET / HTTP/1.1\r\n\r\n" >&3 ◦ while read line <&3; do echo $line; done • command1 || command2で失敗時処理 • ((i++))などの演算や、for ((i=0;i<10;i++))の記述 • declare -n や local -n で変数の参照を得る • {a,{b,c}d}e → ae bde cde のようなブレース展開 • ENV=param commandで、command実行時のみENVを変える シェル芸の基礎:シェル機能 16
闇の魔術 :(){ :|:&; };: 絶対に実行してはいけない(cf. forkbomb) function colon() { colon
| colon& } colon 片方 (:&) がバックグラウンドプロセスになり、killできない プロセステーブルが飽和し、端末が死亡 閑話休題 シェル芸の基礎:シェル機能 17
シェル芸に関わる規範たち 18
UNIX哲学 一つのことを行い、またそれをうまくやるプログラムを書け。 協調して動くプログラムを書け。 標準入出力(テキスト・ストリーム)を扱うプログラムを書け。標準入出力 は普遍的インターフェースなのだ。 https://ja.wikipedia.org/wiki/UNIX哲学 シェル芸に関わる規範たち 19
POSIX • Portable Operating System Interfaces • https://pubs.opengroup.org/onlinepubs/9699919799/ • Xは?→
UNIXからきてる • C標準ライブラリやシェル(sh)の仕様が統一されている • 基本的なコマンド(Utilities)も載っている ◦ awk, cd, chmod, ls, sed, xargs, 他たくさん • 拡張シェル(bash, etc.)は(基本的に)これを守ってる • POSIXの仕様を守っている限りどの環境でも動くはず! シェル芸に関わる規範たち 20
sedとawkはPOSIX準拠 現在でも幅広くsedやawkが使われている理由の一つ (もちろんテキスト処理に特化しているというのもある) ただしGNU sed/awkなど独自拡張を行っているものもある • sed -r、sed -i、sed -y
• awkの各種強力な関数(丸投げ) 環境依存を気にするようになったら一歩沼に沈んだ証 シェル芸に関わる規範たち 21
GNU Coreutils 流石にPOSIXコマンドだけじゃ足りないことも多いので、 追加で存在を前提とされるコマンド群がある fmt, shuf, tee, seq, factorなど 一部コマンドは
POSIX にオプション拡張したものもある Coreutilsをさらに拡張したMoreutilsもある シェル芸に関わる規範たち 22
シェルでできる便利なコマンド 23
$ { time sleep 1 &>/dev/null; } 2>&1 | tail
-3 | awk '{print $2}' | xargs | tr ' ' , 0m1.052s,0m0.009s,0m0.021s # sleep 1を任意のコマンドに置き換えれば計測自動化できる # Bashのtimeコマンドの出力に依存している # for文や>>リダイレクトで複数条件計測とcsv錬成ができる シェルでできる便利なコマンド 24 $ time sleep 1 <空行> real 0m1.052s user 0m0.009s sys 0m0.021s | tail -3 | awk... 0m1.052s 0m0.009s 0m0.021s | xargs 0m1.052s 0m0.009s 0m0.021s
$ $(pbpaste) | pbcopy # macos $ $(xsel -b) |
xsel -bi # Linux (X) # Clipboardのコマンドを実行した結果をClipboardに入れる pbcopy/pbpasteは標準で入っている xselはパッケージマネージャを通してインストール可能 シェルでできる便利なコマンド 25
CSI(Control Sequence Introducer) ESC(0x1b) [ のエスケープシーケンスを入力することで様々な端 末制御が可能となる 文字色・カーソル移動・文字削除・端末サイズ変更、etc. • sh
→ printf '\x1b[31mRED\x1b[m' • bash → echo -e '\x1b[31mRED\x1b[m' • zsh → echo '\x1b[31mRED\x1b[m' RED # 表示設定(m):前景色(30)が赤(1)になる=31m もっと直感的に指示したい場合はtputコマンドがある 26 シェルでできる便利なコマンド
シェル芸人御用達コマンド・イディオム 27
# 整形コマンドとしてのxargs $ seq 12 | xargs -n 3 1
2 3 4 5 6 7 8 9 10 11 12 # 通常xargsは標準入力を最後尾に配置してコマンド実行する $ ls | xargs tar cvf dir.tar # が、コマンドを書かないとただの整形コマンドと化す $ echo -e "many spaces \tand\ttabs\!\!" | xargs many spaces and tabs!! シェル芸人御用達コマンド・イディオム 28
# 任意箇所に埋め込むxargs $ ls | xargs -I{} echo "There is
{} here." There is Desktop here. There is Documents here. … # I(large i)オプションによって任意の場所に埋め込める # 直後に指定した文字列を置換する # 複数箇所指定も可能 シェル芸人御用達コマンド・イディオム 29
$ seq 10 | tr '\n' ' ' $ seq
10 | tr -d '\n' 1 2 3 4 5 6 7 8 9 10 # 改行をスペースに変換する 12345678910 # 改行を消滅させる # この方法は一番最後の改行(10\n)も対象なことに注意 シェル芸人御用達コマンド・イディオム 30
$ seq 10 | tee >(tac | xargs > rev.txt)
| xargs | tr ' ' + | bc 55 # cat rev.txt -> 10 9 8 7 6 5 4 3 2 1 # teeコマンドは本来ファイルと標準出力へsplitさせる # Process Substitutionによって2つのコマンドに渡せる # 並行処理なので両方とも標準出力に流すと大変 # 環境を気にしないのならpeeコマンド(moreutils)が便利 $ seq 10 | pee "tac | xargs > rev.txt" "xargs | tr ' ' + | bc" シェル芸人御用達コマンド・イディオム 31
$ echo Helloworld | grep -o . H e l
l o w o r l d # grepは基本的にマッチした行を抜き出す # -oはマッチした箇所のみを抜き出す # . は任意の1文字なので、全文字が分割表示される シェル芸人御用達コマンド・イディオム 32
$ yes 'echo $RANDOM' | head -3 | bash 28995
29287 23092 # コマンドを自力で生成してからpipe先のbashに投げて実行 # 複雑なコマンドを生成するもよし、 # ランダム要素のあるコマンドを何回も実行するときも便利 # seqをパイプすればfor文より見た目がエレガント[要出典] シェル芸人御用達コマンド・イディオム 33
$ shuf -ren10 {大,中,小,末,}吉 {大,}凶 # おみくじ10連打 • -r 再抽選可
• -e 標準入力ではなく引数をシャッフル • -n10 10回出力 # Q. 本当に御用達なんですか? # A. 他に書くとこがなかった シェル芸人御用達コマンド・イディオム 34
$ sudo cat /var/log/auth.log | grep "Invalid user" | cut
-f9 -d' ' | sort | uniq -c | sort -nr | head -10 # ssh不正ログインしてこようとしたusernameを暴く # Ubuntu 18.04で動作した # sort | uniq -c | sort -nr は最頻ランキングを作るのに便利 # cut -fnum -d' ' はスペースで区切られたnum番目を取得 シェル芸人御用達コマンド・イディオム 35
難読化 36
$ $(echo d)$’\x61’$(echo dGUK | base64 -d) Mon Mar 9
09:46:30 JST 2020 # それぞれ展開すると “date” になる # シェルは展開できるものを全て展開した後に解釈する • echo d → d • $'\x61' → a • echo dGUK | base64 -d → te 難読化 37
難読化テクニックたち echo $[] → 0 ($[]は算術演算、何もないと0) echo ${##} → 1
($#:引数の数=0、${#var}:文字列長) $(: shutdown -h now) (一瞬ひりつかせるが何もしない) /???/???/???1??? (/usr/bin/sha1sumを呼ぶ、環境依存) cut -c n (標準入力のn文字目を取り出す。切り貼りする) 難読化 38
ところで Connpassページのシェル芸、Bashで実行できます $ pbpaste | bash ShellGei!! 難読化 39
どういうこと $ pbpaste | bash -x でデバッグできる ___=$(.&>/???/??/${##}); ___に .
&>/dev/fd/1 の出力を代入する .コマンドがエラーを返すので、それをfd1にリダイレクト -bash: .: ファイル名が引数として必要です .: 使用法: . filename [arguments] __=$? __に$?(直前コマンドの終了ステータス=2)を代入 難読化 40
つづき ! ___=${___##*.} ___に、___の最後の.以降の文字列を代入 -bash: .: ファイル名が引数として必要です .: 使用法: .
filename [arguments] 言語環境に依存しない部分を抽出(このメッセージ自体はBashの builtinなので、Bashで実行している限り変わらない) 難読化 41
つづき ____=$(${___:$(($__$#-$?)):$?}${___:$__*$__:$?}${___:$ (($__$#-$__)):$?} -${___:$(($__#$?$?$#$?)):$?}&>/???/??/$?) 先ほどのコマンドで!をつけたので、$?が反転して1になる $#は0、これらで$___=' filename[arguments]'を切り貼り ____=$(set -g &>/dev/fd/1)
bash: 1 行: set: -g: 無効なオプションです set: 使用法: set [-abefhkmnptuvxBCHP] [-o option-name] [--] [arg ...] 難読化 42
つづき これらを繰り返して最終的に ___=(eval $(echo {a..\u7a})) ___=(a b c d e
… x y z) # ___はarrayになる を取得 配列インデックスをいじって任意コマンドが実行できる 難読化 43
さいごに 44
シェル芸勉強会 • 2ヶ月に1回新宿で開催される勉強会 • 界隈がfreakyで面白い(沼にハマった人たちを参考) • シェルのワンライナーという制約下で8問解く 例えば: 日経のページから日経平均株価の日次データをダウンロードし て、毎月の終値の最高値と最安値を出力してください。
https://b.ueda.tech/?post=20191228_shellgei_45#q2 勉強会リンク(https://usptomo.doorkeeper.jp/) 45 さいごに