第25回もう4年もやってんのかシェル芸勉強会に参加させて頂きました!

LTも面白いシェル芸勉強会
kanata7年以上前に追加

シェルスクリプト大好きなんですが、新しい知見が得られて、やっぱり面白いですね!
問題解説は、本家のサイトが詳しいので、そちらにお任せするとして、ここは私なりの感想と解説(?)をしたいと思います。

【問題と解答】第25回もう4年もやってんのかシェル芸勉強会

jus共催 第7回初心者の定義で大揉め午前のシェル勉強会/第25回もう4年もやってんのかシェル芸勉強会

Q1

 www.usptomo.comのIPアドレスだけを出力するワンライナーを考えてみてください。

解答&解説

digでもpingでもnslookupでも出来るけど、なぜかtracerouteを思いついた。
ちなみにnslookupを使う人はおじさんらしい。

$ traceroute www.usptomo.com | head -1 |awk '{print $4}'|tr -d '(),'
157.7.203.188

Q2

次のような出力を作ってください。

ひらけ!ポンキッキ
らけ!ポンキッキひ
け!ポンキッキひら
!ポンキッキひらけ
ポンキッキひらけ!
ンキッキひらけ!ポ
キッキひらけ!ポン
ッキひらけ!ポンキ
キひらけ!ポンキッ

解答&解説

ぜんぜん解けなかったw
ループ使うしなないかな、とか思ってたんだけど、ループ無しでも解けるそうで、目から鱗。

$ yes 'ひらけ!ポンキッキ' | tr -d '\n' | fold -w 30 | head -n 9 | sed 's/.$//'

これずげぇ。

Q3

rbashと打つとリダイレクトが使えなくなります。

この状況で、/etc/passwdからbashをログインシェルにしているユーザのレコードを抽出し、hoge等のファイルに出力してみましょう。様々な方法を考えてみましょう。bashと打ったりexitでもとのbashに戻るのは反則とします。

解答&解説

自分の環境には、rbash入ってなかったんだけど(?)、bash -r と同等らしい。これを使うとリダイレクトとTAB補完その他が制限されるという鬼畜仕様。

要は、リダイレクトを使わずにファイルに出力する方法を思いつけば解ける。その時に出たファイル出力するコマンドを以下に挙げておきます。

  • sort -o file
  • dd of=file
  • awk '{print $0 > "file"}'
  • sed 'w file'
  • iconv -o file
  • cp /dev/stdin hoge

Q4

以下のひらがなからワンライナーを始めて、濁点がつく字だけに濁点をつけてみてください。

解答&解説

無理だった。
ASCIIコードの英小文字と英大文字は32を足したり引いたりすると変換できるんだけど、その応用かな?とか考えてた。

nkfだった。nkf芸。

$ echo すけふぇにんけん | sed 's/./&゛/g'| nkf --katakana | nkf -Z4 | nkf --hiragana | sed 's/゛//g'
ずげぶぇにんげん

Q5

1秒に一つ*が伸びていくアニメーションを作ってください。

解答&解説

お、こりゃー解けるよ。

#!/bin/bash

for i in $(seq 1 100)
do
  printf '*'
  sleep 1
done

これを一行にする。

$ for i in $(seq 1 100);do printf '*'; sleep 1;done

Q6

日本語のメッセージから作った次の文字列を復元してください。

$ xxd crypt 
0000000: 6237 3330 6137 3330 6562 3330 6238 3832  b730a730eb30b882
0000010: 3061 3030 0a                             0a00.

解答&解説

おおっ。CTFっぽい!燃える!(と思ったけど、自分が解くより他の方が先に解いてた)

目grep力がある人ならば

b730
0a00

あたりで、ピンと来る・・・か。リトルエンディアンになっているね。で、2Byte文字っぽくて、0x30から始まる・・・となると、Unicodeだと解る、と。

なので、リトルエンディアン変換&Unicodeをお使いの環境(UTF-8)に変換するには、こんな感じ、と。
なるほど。

$ cat crypt | xxd -ps -r | iconv -f=ucs-2le -t=utf8

ちなみに、 UnicodeとUTF-8って何が違うの? っていうのは、私がまとめた 文字コードの解説 があるので、ご参考にどうぞ。

Q7

本日(2016年10月29日)の範囲の毎秒のUNIX時刻で素数となるものを全て列挙してください。出力はUNIX時刻でなく、何時何分何秒か分かるようにしましょう。世界標準時で考えてください。

解答&解説

お、これもなんかできそう。

$ seq $(date -d '2016/10/29' -u +%s) $(date -d '2016/10/29 1 day' -u +%s) | factor | awk 'NF==2{print $2}'|xargs -n1 -I% date -ud @%

分解すると、
2016年10月29日の範囲の毎秒のUNIX時刻

$ seq $(date -d '2016/10/29' -u +%s) $(date -d '2016/10/29 1 day' -u +%s) 

素数の判別

$ seq 1 100| factor | awk 'NF==2{print $2}'

通算秒から、普通のフォーマットに変換

$ echo 1477785349 | date -ud -

Q8

次のようにサイン波を描いてください。

20161030_shellgei_q8.png

解答&解説

も、もぅ無理。サイン波は、なんとか出せるとして、それの縦横をひっくり返すのが至難。

結局、Tukubaiのtateyokoコマンドを使うか、rsコマンドを使う解法でした。

なんか、普通に用意されているコマンドで出来たような気もするんだけど、思い出せなかった。

$ seq 1 20 | awk '{a=sin($1/3) * 10 + 10;for(i=0;i<a;i++)printf "@ ";printf "* ";for(i=a;i<20;i++)printf "@ ";print ""}' | rs -t 23 | tr @ ' '

懇談会&LT

いや、これめっちゃ面白かった!!
モバイルバッテリーの研究とか、ゲノムにまつわるシェル芸の応用とか、ちょっと、自分もLTやってみようかな。
CTFにおけるシェル芸の応用とか。

20161030_shellgei_q8.png (31.659 KB) kanata, 2016/10/30 11:28


コメント

kanata7年以上前に追加

当日の動画

クリップボードから画像を追加 (サイズの上限: 100 MB)