第25回シェル芸勉強会参加報告
2016-10-29(土)に開催された、第25回シェル芸勉強会(正式名称:jus共催 第7回初心者の定義で大揉め午前のシェル勉強会/第25回もう4年もやってんのかシェル芸勉強会)に参加しました。
ただ、在住地の関係で直接会場へ伺うことは出来なかったため、Youtubeで配信してくださったライブ中継を利用して、遠隔で参加しました。
勉強会は、午前と午後の2部構成でした。
午前は、シェルに関する勉強会で、manページ用いた読書勉強会でした。
午後は、シェル芸勉強会で、シェル芸力を付けるための問題を解きました。
以下、勉強会の詳細を記します。
実行環境
Arch Linux 4.8.4-1-ARCH
GNU bash 4.3.46
GNU coreutils 8.25-2
GNU diffutils 3.5-1
GNU findutils 4.6.0-2
util-linux 2.28.2-1
grep (GNU grep) 2.26
sed (GNU sed) 4.2.2
gawk 4.1.4
nkf 2.1.4
xxd V1.10 27oct98
gnuplot 5.0
usp Personal Tukubai (20160402、 Open usp Tukubaiで代用可能)
シェルに関する勉強会
manページ読書会
シェル芸おじさんこと、USP友の会 会長の上田 隆一( @ryuichiueda )さんによる、manページを読んでコマンドへの理解を深める内容でした。
今回は、有名なUnixコマンド、grepに関して、manページを読み進めました。
頻繁に使用するコマンドなので、分かりきっていると思っていたけれど…
改めてきちんとmanページを読んでみると、まだまだ知らないことだらけだったり。
以下、個人的に気になった内容。
GNU grepのfgrep egrepは、実はシェルスクリプトになっていて、中でgrepをオプション付きで呼び出しているだけ
→ BSDのgrepは、fgrep egrep共にバイナリだった。GNU grepは、処理速度が非常に高速で、GNU脱却を目指しているFreeBSDプロジェクトでも、なかなかリストラ出来ないとか
→ 参考: 第74回 FreeBSD 12,GNU rcsをベースから削除:BSD界隈四方山話|gihyo.jp … 技術評論社-Fオプションは、単純なフィルタ処理をおこなう分、処理速度やメモリ消費に優れる
-eオプションを使うことで、複数のパターンを指定できる
例:
$ echo -e 'hoge\nhage\nhige' | grep -e 'hoge' -e 'hige'
hoge
hige
-qオプションを使うことで、条件分岐に利用できる
例:
$ cat profile
身長 178
体重 68
髪の毛 none
$ [ $(grep -q 'none' profile) ] || echo 'hage'
hage
$ wc -l hoge 3000000000 hoge $ head hoge 1 2 3 4 5 6 7 8 9 10 $ time grep '404' hoge >/dev/null real 0m0.013s user 0m0.007s sys 0m0.003s $ time grep -F '404' hoge >/dev/null real 0m0.009s user 0m0.003s sys 0m0.003s
- 結果
-Fオプションを付けたほうが、(ちょっとだけ)速いらしい。
また、 @MasWagさんによれば、grep -Fは、 エイホ–コラシック法で実装されている(いた?)らしい。
grep -F は典型的にはAho-Corasickで動く #シェル芸
— Masaki Waga (@MasWag) 2016年10月29日
第25回シェル芸勉強会
問題文および模範解答は、以下のURLから。
https://blog.ueda.asia/?p=8737
問1
www.usptomo.com のIPアドレスを調べる問題。
digるなり、pingるなり、nslookupるなり。
てか、digに+shortなんてオプションがあったのね…
01 #!/bin/sh
02
03 dig www.usptomo.com |
04 sed -n '/ANSWER SECTION/{n; p}' |
05 awk '$0=$NF'
以下、コピペ実行用のワンライナーコード。
dig www.usptomo.com | sed -n '/ANSWER SECTION/{n; p}' | awk '$0=$NF'
問2
前日 の復習(?)問題。
「響け!ユーフォニアム」と同じコードで。
awkを使って、堅実に出力する。
変態的な解答をお探しの方は、上記のTogetterまとめへどうぞ…w
01 #!/bin/sh
02
03 echo ひらけ!ポンキッキ |
04 awk -vFS= '$1=$1' |
05 awk '{for(i=1;i<=NF;i++){print}}' |
06 awk '{for(i=NR;i<=NF;i++){printf $i}; for(i=1;i<NR;i++){printf $i}; print ""}'
以下、コピペ実行用のワンライナーコード。
echo ひらけ!ポンキッキ | awk -vFS= '$1=$1' | awk '{for(i=1;i<=NF;i++){print}}' | awk '{for(i=NR;i<=NF;i++){printf $i}; for(i=1;i<NR;i++){printf $i}; print ""}'
問3
リダイレクトを制限した状態で、特定ファイルをフィルタした結果を、ファイルへ書き出す問題。
僕の環境では、rbashは存在しなかったので、同様の機能を持つ以下のコマンドで代用した。
$ bash -r
幾つかのコマンドは、自身でファイルに出力する機能を持っているので、リダイレクトの代わりにそれらを利用すればOK。
awkのリダイレクト機能で。
01 #!/bin/sh
02
03 cat /etc/passwd |
04 awk -F: '$NF ~ /bash/{print > "hoge"}'
sedのwコマンドで。
01 #!/bin/sh
02
03 cat /etc/passwd |
04 sed -n '/\/bin\/bash$/w hoge'
以下、コピペ実行用のワンライナーコード。
cat /etc/passwd | awk -F: '$NF ~ /bash/{print > "hoge"}'
cat /etc/passwd | sed -n '/\/bin\/bash$/w hoge'
問4
ひらがな文字列に濁点をつける問題。
nkfだけだと難しかったので、Tukubaiを解禁。
いったん半角カナに変換し、その状態で全ての文字に半角濁点を付加する。
その後、全角カナに戻せば、濁点がつけれる文字は濁点付きに、そうでない文字は、元の文字+全角濁点になる。
後は、余分な全角濁点を除去し、出力を整形すればOK。
01 #!/bin/sh
02
03 echo すけふぇにんけん |
04 nkf --katakana |
05 han |
06 sed 's/./&゙/g' |
07 zen |
08 nkf --hiragana |
09 sed 's/″//g'
以下、コピペ実行用のワンライナーコード。
echo すけふぇにんけん | nkf --katakana | han | sed 's/./&゙/g' | zen | nkf --hiragana | sed 's/″//g'
ちなみに、nkfにも全角 → 半角変換をおこなう機能、-Z4オプションなんてものがあるそう。
ただ、この-Z4オプションは、残念ながらmanページには書かれていないみたい…
(nkf --helpすると、一応記載はされているようだけれど。)
問5
進捗状況のようなアニメーションを作る問題。
実はこの問題、題意をちょっと勘違いしていた…
僕の環境では、ブラウザ上で「ファイルをダウンロード」と表示されていたので、てっきりダウンロード画面のようなアニメーションを作ると思っていた。
でも、実際には、1秒毎に"*"の文字が増えるだけで良かったらしい。
01 #!/bin/sh
02
03 seq 1 inf |
04 awk '{printf "clear; echo ファイルをダウンロード; echo '\''"; for(i=1;i<=$0;i++){printf "*"}; print "'\''; sleep 1"}' |
05 sh
せっかくなので、もっとシンプルなバージョンを。
01 #!/bin/sh
02
03 yes 'printf "*"; sleep 1' |
04 sh
以下、コピペ実行用のワンライナーコード。
seq 1 inf | awk '{printf "clear; echo ファイルをダウンロード; echo '\''"; for(i=1;i<=$0;i++){printf "*"}; print "'\''; sleep 1"}' | sh
yes 'printf "*"; sleep 1' | sh
問6
暗号化された文字列を復元する問題。
この問題は、今回の勉強会で全く歯が立たなかった…orz
分かる人には分かるそうだけれど、暗号文がリトルエンディアンになっているとの事。
…ごめんなさい、僕には見ただけでは分からなかったですw
という訳で、模範解答を参考にしつつ、改めて正答を考えてみた。
01 #!/bin/sh
02
03 cat crypt |
04 sed 's/\(..\)\(..\)/\2\1/g' |
05 xxd -r -p |
06 nkf -W16
以下、コピペ実行用のワンライナーコード。
cat crypt | sed 's/\(..\)\(..\)/\2\1/g' | xxd -r -p | nkf -W16
問7
2016年10月29日の範囲の秒数で、UNIX時間で素数になるものを出力する問題。
これは、 シェル芸スパルタン演習第9回で似たような問題をやったので、余裕だぜ…!!
01 #!/bin/sh
02
03 seq $(date -u --date 20161029 +%s) $(date -u --date 20161030 +%s) |
04 sed '$d' |
05 factor |
06 awk 'NF==2&&$0=$2' |
07 xargs -n1 -I% date -u --date @%
以下、コピペ実行用のワンライナーコード。
seq $(date -u --date 20161029 +%s) $(date -u --date 20161030 +%s) | sed '$d' | factor | awk 'NF==2&&$0=$2' | xargs -n1 -I% date -u --date @%
問8
CLI上で正弦波を出力する問題。
この問題は、個人的に問6の次に難しかった…
というのも、一応理系出身なのに、数学はさっぱりなので…orz
…なので、横着してgnuplotさんに正弦波を出してもらった♥
01 #!/bin/bash
02
03 gnuplot <(echo -e 'set terminal dumb\nplot sin(x)')
以下、コピペ実行用のワンライナーコード。
gnuplot <(echo -e 'set terminal dumb\nplot sin(x)')
正攻法な解法は……勘弁してくださいorz
参照Webサイト
us共催 第7回初心者の定義で大揉め午前のシェル勉強会/第25回もう4年もやってんのかシェル芸勉強会
→ 勉強会の概要。シェル芸 のライブ ストリーム(午後)
→ 今回の勉強会の動画配信(アーカイブ)。jus共催 第7回初心者の定義で大揉め午前のシェル勉強会/第25回もう4年もやってんのかシェル芸勉強会 - Togetterまとめ
→ 参加者の当日の様子。第25回シェル芸勉強会へ遠隔参加 - 日々之迷歩
→ 大阪・福岡のサテライト会場、主催者さんの記事。
雑記
ここ最近、CLIに触る機会が減っており、シェル芸力の衰えを感じたので、この数週間は過去問を解いて修行をしていました。
全21回分の問題を解いて、かなり実力がついたんじゃないのかなーと思っていたのだけれど…
→ 今回、8問中2問解けませんでしたorz
→ Unixだけでなく、問6のように低レイヤの知識が必要になる事もあったり、シェル芸はまだまだ奥が深いぜ…!!とはいえ、今回の問題は、文字列操作から日付操作、数学関連に、更には暗号解析と、バリエーション豊富で楽しめました!
次回は……会長によれば、エクシェル芸が出題されるとか…!?
— Ryuichi Ueda (@ryuichiueda) 2016年10月29日
多少はシェル芸が分かるようになったし、僕自身の状況も少し落ち着いてきたので、そろそろ名古屋サテライト会場について考えてみたかったり。
とはいえ、勉強会を開催した経験は無いし、そもそも中度のコミュ症なので、果たして主催なんて出来るのかという不安もあったり…… _(:3」∠)_
まあ、焦らずのんびりと考えていきたいと思っています。
いつも遠隔での参加になってしまいますが、毎回とても楽しめているうえに、新しい発見ばかりで、非常に勉強になります。
勉強会を開催してくださった、上田会長をはじめとした日本UNIXユーザ会とUSP友の会の皆様、今回もありがとうございました!!