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
700
CTFで学ぶPHPセキュリティ
ryotosaito
3
4.4k
Other Decks in Programming
See All in Programming
AIエージェント時代のコードレビューを設計する
nogu66
6
2.7k
Go のフラットな パッケージに 「ファイル単位の private」を 〜Linter “declscope” を作った話〜
mpyw
0
320
Go × SIMDで高速化するベクトル検索 ~ルーフラインモデルでSIMDが効く境界を探れ! ~
po3rin
1
920
iOSDC Japan 2026 - Swiftで作って学ぼう!データベース自作入門
kaseken
2
160
How I Stole PSI from Android Studio - DroidKaigi2026
worker8
0
130
SONY CISC-NEWS NWS-1750 + NWB-225 フレームバッファの NetBSD/news68k ドライバ実装 / OSC2026Hiroshima
tsutsui
0
110
AHC070解法紹介
eijirou
0
120
Webの地図
yosuke_furukawa
PRO
6
4.5k
Claude Codeを組織的に動かして月400PRを実現した話
happy_ryo
0
280
Jetpack Compose メカニズム
skydoves
0
420
XP祭りでしか伝わらないフリップネタ #xpjug
murabayashi
0
150
技術的負債を組織課題として解く-増えすぎたマイクロサービスとの戦い-
reimaru
1
1.8k
Featured
See All Featured
実際に使うSQLの書き方 徹底解説 / pgcon21j-tutorial
soudai
PRO
202
76k
Paper Plane
katiecoart
PRO
4
53k
Exploring the Power of Turbo Streams & Action Cable | RailsConf2023
kevinliebholz
37
6.6k
Product Roadmaps are Hard
iamctodd
55
13k
The State of eCommerce SEO: How to Win in Today's Products SERPs - #SEOweek
aleyda
2
12k
Visual Storytelling: How to be a Superhuman Communicator
reverentgeek
2
660
Making the Leap to Tech Lead
cromwellryan
135
10k
Prompt Engineering for Job Search
mfonobong
0
450
How to optimise 3,500 product descriptions for ecommerce in one day using ChatGPT
katarinadahlin
PRO
3
3.8k
Designing for Timeless Needs
cassininazir
1
480
Being A Developer After 40
akosma
91
590k
Agile Actions for Facilitating Distributed Teams - ADO2019
mkilby
0
280
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 さいごに