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
730
CTFで学ぶPHPセキュリティ
ryotosaito
3
4.5k
Other Decks in Programming
See All in Programming
Augmenting AI with the Power of Jakarta EE
ivargrimstad
0
580
Snowflake Openflow Connector利用の勘所 / 20261024developersio2026tokyo-snowflake-openflow
kasacchiful
PRO
0
290
SODA - FACT BOOK(EN)
sodainc
1
200
自作Discord音声botをLambda MicroVMsに移行した話 / Migrating My Discord Voice Bot to Lambda MicroVMs
akihisaikeda
1
290
LLM 101
dalinaum
0
470
まずはコードより業務と向き合う:テーブル解体のためにPdMを呼んだ話
sakawe_ee
0
150
クラウドエージェントは、 何がそんなに便利なのか / what makes cloud agents so useful
rkaga
5
770
AI-Powered Domain-Driven Design
ziobrando
0
390
AIがコードを書いてくれる時代、我々は何を確かめるのか
yosuke_furukawa
PRO
13
5.7k
Railsバージョンを4倍にした話
optim
0
930
Python Lambdaにおけるテストしやすい設計とAI支援の活用 / Designing Testable Python Lambda Functions with AI
kitano_yuichi
1
290
複数ドメインを一つのアプリに統合するFlutterの設計と運用_FlutterKaigi2026登壇資料(須永高弘)
takahirosunaga
0
150
Featured
See All Featured
The Anti-SEO Checklist Checklist. Pubcon Cyber Week
ryanjones
0
290
Gemini Prompt Engineering: Practical Techniques for Tangible AI Outcomes
mfonobong
2
630
Git: the NoSQL Database
bkeepers
PRO
433
67k
Java REST API Framework Comparison - PWX 2021
mraible
34
9.8k
RailsConf & Balkan Ruby 2019: The Past, Present, and Future of Rails at GitHub
eileencodes
141
35k
[Rails World 2023 - Day 1 Closing Keynote] - The Magic of Rails
eileencodes
38
3.1k
What's in a price? How to price your products and services
michaelherold
247
13k
Mozcon NYC 2025: Stop Losing SEO Traffic
samtorres
1
600
Leo the Paperboy
mayatellez
10
2.4k
Exploring the relationship between traditional SERPs and Gen AI search
raygrieselhuber
PRO
4
4.4k
Sam Torres - BigQuery for SEOs
techseoconnect
PRO
0
610
Design of three-dimensional binary manipulators for pick-and-place task avoiding obstacles (IECON2024)
konakalab
0
650
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 さいごに