第28回基準値を超えるシェル芸勉強会のまとめ

Pocket
LINEで送る

参加者の方々、会場でお手伝いいただいた方々、サテライトの主催・参加のみなさま、会場を提供いただいたさくらインターネットさん、横田さん、午前講師の今泉さん、共催のjusさん並びにりゅうちさん、LT発表者のみなさま、ありがとうございました。

総括的なコメント

最近、会場の半分くらいの人たちのレベルが人間離れしていますが、初心者でも楽しめる雰囲気はキープできたかと・・・。問題は実用的かつ高難易度でした。

今回は募集が早すぎてドタキャンが多くゆったりめでした。

問題はこちらです。

話が前後しますが、午前の部は今泉さんのシグナルに関するレクチャーでした。ありがとうございました。個人的には擬似シグナル0番というのを知らなかったです。

当日の様子

Twitter上での様子

サテライトの様子

大阪のLTのスライドはこちらにあります。

LTやブログのリンク

写真など

昼食
LT

Pocket
LINEで送る

【問題と解答】第28回基準値を超えるシェル芸勉強会

Pocket
LINEで送る

問題のみのページはこちら

問題で使うファイル等

GitHubにあります。ファイルは

https://github.com/ryuichiueda/ShellGeiData/tree/master/vol.28

にあります。

クローンは以下のようにお願いします。

$ git clone https://github.com/ryuichiueda/ShellGeiData.git

環境

解答例はUbuntu Linux 16.04 で作成。Macの場合はcoreutilsをインストールの上、gsedをつかいましょう。BSD系の人は玄人なので各自対応のこと。

注意

今回はいつにも増して一般解を出そうとすると死にますので、欲しい出力が得られればそれで良いということを心がけましょう。

イントロ

Q1

Q1.1

contents.txtについて、「\begin{figure}と\end{figure}」で囲まれた部分を全て抽出してください。

Q1.2

次のようなリストを作ってください。

世界座標系とロボットの姿勢 ./figs/coordinate.eps
計測値 ./figs/observation.eps
ランドマークの計測値から2点の相対姿勢を求める ./figs/two_poses.eps
ランドマークの計測値の不確かさを表す共分散行列 ./figs/observation_noise.eps

解答

Q1.1については、次のようにsedの範囲指定を使います。

$ cat contents.tex | sed -n '/\\begin{figure}/,/\\end{figure}/p'
\begin{figure}[htbp]
	\begin{center}
		\includegraphics[width=0.5\linewidth]{./figs/coordinate.eps}
		\caption{世界座標系とロボットの姿勢}
		\label{fig:coordinate}
	\end{center}
\end{figure}
(中略。略していないものも含めて全部で4つ)
\begin{figure}[htbp]
	\begin{center}
		\includegraphics[width=0.8\linewidth]{./figs/observation_noise.eps}
		\caption{ランドマークの計測値の不確かさを表す共分散行列}
		\label{fig:observation_noise}
	\end{center}
\end{figure}

Q1.2については、不要なデータを削って最後に並び替えます。

$ cat contents.tex | sed -n '/\\begin{figure}/,/\\end{figure}/p' |
 grep -e include -e caption | sed 's/.*{//' |
 xargs -n 2 | tr -d '}' | awk '{print $2,$1}'
世界座標系とロボットの姿勢 ./figs/coordinate.eps
計測値 ./figs/observation.eps
ランドマークの計測値から2点の相対姿勢を求める ./figs/two_poses.eps
ランドマークの計測値の不確かさを表す共分散行列 ./figs/observation_noise.eps

Q2

\sectionから始まる部分を章としたとき、第2章の第1文を抽出してみましょう。ただし、各行の%以降はコメントアウトされた文なので無視してください。

解答

最初に段落番号をつけると簡単になります。

$ awk '/\\section/{a+=1}{print a,$0}' contents.tex | grep ^2 |
 grep -v '\\section' | grep -v '%.*' | sed 's/^..//' |
 sed -n '1,/。/p' | sed 's/。.*/。/'

平面上を移動し、向きを持ち、カメラでランドマーク観測ができるロボットで
graph-based SLAMを実行する方法を考える。

Q3

脚注(\footnote{…})の部分を全て抽出してください。一つだけ、脚注の中にも{}で囲まれた部分があるので注意してください。

解答

まずは脚注の終わりが必ず「。」で終わっているのを利用したズル解答から。grep -Pの最短一致を使います。

$ tr -d '\n' < contents.tex | grep -oP '(\\footnote{.+?。})'
\footnote{この仮定は実用上強すぎるが、実際には、後の計算式から分かるように、2つの姿勢間での値$\psi_{c,t}, \psi_{c,t'}$の差だけが分かれば良い。例えば、2点間で得られた画像の向きを画像処理から割り出すなどの処理で、この差は得られる。}
\footnote{$「10$[\%]」は変数にすべきだが、記号が増えて理解の妨げになるので固定値として説明する。}
\footnote{おそらく$\psi$は$\theta$で置き換えられるので$\psi$を使わない実装もできるが、まだ自分自身では検証していない。}
\footnote{小さい角度なので、$\sin(3\pi/180)$は$3\pi/180$に近似しても良い。}
\footnote{固定しないと世界座標系が決まらない。}

そうでない解は、インデントをつけてから抽出する方法しか、今のところ思いついていません。

$ tr -d '\n' < contents.tex | sed 's/[{}]/\n&\n/g' | sed 's/\\footnote/\n&/' |
 awk '{for(a=0;a<i;a++)printf " "}/{/{i+=1}/}/{i-=1}{print}' |
 sed -n '/\\footnote/,/^ }/p' | tr -d '\n' | sed 's/\\footnote/\n&/g' |
 sed 's/ *} */}/g' | sed 's/ *{ */{/g' | awk '{print}'

Q4

各章(\sectionから次の\sectionまでの部分)を、ファイル名にタイトルをつけて個別のファイルに分けてください。ファイル名のスペースはアンダースコアに変えても構いません。

解答

$ cat contents.tex |
 awk '/\\section/{f=gensub(/ /,"_","g",$0);gsub(/\\section{/,"",f);
gsub(/}$/,"",f)}{print $0 > f}'
###このようにファイルができます###
$ ls
contents.tex  graph-based_SLAMの実装例  はじめに  問題

Q5

このテキストには「○○座標系」という用語がいくつか出てきます。○○にはカタカナか漢字の単語が入ります。これらの「○○座標系」を全通り抽出してください。

解答

$ grep 座標系 contents.tex | mecab -O wakati |
 grep -oE '[^ あ-ん]+ 座標 系' | sort -u | tr -d " "
ロボット座標系
計測座標系
世界座標系
$ grep 座標系 contents.tex | grep -oE '[^ あ-ん{、「]+座標系' | sort -u
ロボット座標系
計測座標系
世界座標系

Q6

各段落の頭に全角スペースを入れてください。

解答

空行を見つけてフラグを立て、普通の文頭かどうか判断して全角スペースを差し込みます。

$ cat contents.tex |
 awk '/^ *$/{f=1}
{if(f && !/^ *$|section|begin|end|^%/){print " "$0;f=0}else{print}}'

Q7

本文の余計な改行を取ってください。(段落内の余計な改行を取るということです。)

解答

q6の出力から続ける例を示します。ゴリ押しです。

$ cat q6 | sed 's/^%.*//' |
 awk '/begin/{if(!stop)print "";stop+=1}
  !stop && !/section/{printf($0)}
  stop || /section/{print}/end/{stop-=1}' |
 sed 's/  /n  /' | sed 's/\\[sub]*section/\n\n&/' 

Q8

contents.texについて、次のように章節項のリストを作ってください。

1 はじめに
2 問題
2.1 ロボットの姿勢と座標系
2.2 観測
2.2.1 ランドマークの識別
2.2.2 ランドマークの姿勢計測
2.2.3 計測値の記録
2.2.4 計測値の誤差
2.3 完全SLAM問題
3 graph-based SLAMの実装例
3.1 グラフのエッジを作る
3.1.1 $\V{\mu}_{c,t,t'}, \V{e}_{c,t,t'}$の計算
3.1.2 $\Sigma_{c,t,t'}, \Omega_{c,t,t'}$の計算
3.2 最適化問題を作る
3.2.1 マハラノビス距離
3.2.2 最適化する式
3.3 $\V{e}_{c,t,t'}$の勾配を求める
3.4 問題を解く

解答

awkで章節項のカウンタを作ってうまく制御するのが一番素直な方法です。(二番目以降は思いつきませんが。)

$ grep section contents.tex | sed 's/{/ /' | grep -v ^% |
 sed 's/\\label.*//' | sed 's/}$//' |
 awk '/^\\se/{s+=1;$1=s;ss=0;print}/\\subse/{ss+=1;$1=s"."ss;sss=0;print}/
\\subsub/{sss+=1;$1=s"."ss"."sss;print}'
1 はじめに
2 問題
2.1 ロボットの姿勢と座標系
2.2 観測
2.2.1 ランドマークの識別
2.2.2 ランドマークの姿勢計測
2.2.3 計測値の記録
2.2.4 計測値の誤差
2.3 完全SLAM問題
3 graph-based SLAMの実装例
3.1 グラフのエッジを作る
3.1.1 $\V{\mu}_{c,t,t'}, \V{e}_{c,t,t'}$の計算
3.1.2 $\Sigma_{c,t,t'}, \Omega_{c,t,t'}$の計算
3.2 最適化問題を作る
3.2.1 マハラノビス距離
3.2.2 最適化する式
3.3 $\V{e}_{c,t,t'}$の勾配を求める
3.4 問題を解く
Pocket
LINEで送る

【問題のみ】第28回基準値を超えるシェル芸勉強会

Pocket
LINEで送る

解答例はこちら

問題で使うファイル等

GitHubにあります。ファイルは

https://github.com/ryuichiueda/ShellGeiData/tree/master/vol.28

にあります。

クローンは以下のようにお願いします。

$ git clone https://github.com/ryuichiueda/ShellGeiData.git

環境

解答例はUbuntu Linux 16.04 で作成。Macの場合はcoreutilsをインストールの上、gsedをつかいましょう。BSD系の人は玄人なので各自対応のこと。

注意

今回はいつにも増して一般解を出そうとすると死にますので、欲しい出力が得られればそれで良いということを心がけましょう。

イントロ

Q1

Q1.1

contents.txtについて、「\begin{figure}と\end{figure}」で囲まれた部分を全て抽出してください。

Q1.2

次のようなリストを作ってください。

世界座標系とロボットの姿勢 ./figs/coordinate.eps
計測値 ./figs/observation.eps
ランドマークの計測値から2点の相対姿勢を求める ./figs/two_poses.eps
ランドマークの計測値の不確かさを表す共分散行列 ./figs/observation_noise.eps

Q2

\sectionから始まる部分を章としたとき、第2章の第1文を抽出してみましょう。ただし、各行の%以降はコメントアウトされた文なので無視してください。

Q3

脚注(\footnote{…})の部分を全て抽出してください。一つだけ、脚注の中にも{}で囲まれた部分があるので注意してください。

Q4

各章(\sectionから次の\sectionまでの部分)を、ファイル名にタイトルをつけて個別のファイルに分けてください。ファイル名のスペースはアンダースコアに変えても構いません。

Q5

このテキストには「○○座標系」という用語がいくつか出てきます。○○にはカタカナか漢字の単語が入ります。これらの「○○座標系」を全通り抽出してください。

Q6

各段落の頭に全角スペースを入れてください。

Q7

本文のところだけ改行を取ってください。

Q8

contents.texについて、次のように章節項のリストを作ってください。

1 はじめに
2 問題
2.1 ロボットの姿勢と座標系
2.2 観測
2.2.1 ランドマークの識別
2.2.2 ランドマークの姿勢計測
2.2.3 計測値の記録
2.2.4 計測値の誤差
2.3 完全SLAM問題
3 graph-based SLAMの実装例
3.1 グラフのエッジを作る
3.1.1 $\V{\mu}_{c,t,t'}, \V{e}_{c,t,t'}$の計算
3.1.2 $\Sigma_{c,t,t'}, \Omega_{c,t,t'}$の計算
3.2 最適化問題を作る
3.2.1 マハラノビス距離
3.2.2 最適化する式
3.3 $\V{e}_{c,t,t'}$の勾配を求める
3.4 問題を解く
Pocket
LINEで送る

jus共催第27回シェル芸勉強会のリンク集

Pocket
LINEで送る

2017年2月11日(土曜日)にさくらインターネットさんにて開催しました。日本UNIXユーザ会(jus)さんとの共催でした。

sedに絞って機能を使ってみる出題にしたのでいつもより勉強会っぽい勉強会になりました。最後の三問が急に難しくなって「ハシゴを外された」との声もありましたが・・・。

酸化参加された皆様、会場を提供いただいたさくらインターネットさん横田さん、午前の部の講師の鳥海さん石井さん、ストリーミングを担当された宮川さん、濃いLT勢の皆様、jusのりゅうちさん、Twitter勢の皆様、そしてサテライト会場の皆様、ありがとうございました。

問題

 

録画

サテライト会場

まとめ

ブログ等

多すぎるので今回からまとめのところからのリンクで代用させていただきます・・・

番外編

翌日の別の勉強会で危険シェル芸が炸裂したそうです・・・

Vimシェル芸の予感・・・

Pocket
LINEで送る

【問題と解答】第27回sedこわいシェル芸勉強会

Pocket
LINEで送る

問題のみのページはこちら。

問題で使うファイル等

GitHubにあります。ファイルは

https://github.com/ryuichiueda/ShellGeiData/tree/master/vol.27

にあります。

クローンは以下のようにお願いします。

$ git clone https://github.com/ryuichiueda/ShellGeiData.git

イントロ

環境

対象とするsedはGNU sedだけに絞っています。解答例はUbuntu Linux 16.04 で作成。Macの場合はcoreutilsをインストールの上、gsedをつかいましょう。BSD系の人は玄人なので各自対応のこと。

Q1

次のechoの出力について、偶数番目の文字だけ大文字にしてください。できたら、奇数番目の文字だけ大文字にしてください。

$ echo abcdefghijklmn

解答

###偶数番目を大文字に###
$ echo abcdefghijklmn | sed 's/\(.\)\(.\)/\1\U\2/g'
aBcDeFgHiJkLmN
###奇数番目を大文字に###
$ echo abcdefghijklmn | sed 's/\(.\)\(.\)/\U\1\L\2/g'
AbCdEfGhIjKlMn
###-rを使うと多少スッキリする###
$ echo abcdefghijklmn | sed -r 's/(.)(.)/\U\1\L\2/g'
AbCdEfGhIjKlMn

Q2

seq 1 100から始めてsedだけでFizzBuzzをやってみましょう。

解答

$ seq 1 100 | sed '0~3s/.*/Fizz/;0~5s/$/Buzz/' |
 sed 's/[0-9]*B/B/' | xargs

Q3

次の出力について、3行目を7行目の下に移動してください。

$ seq 1 10

解答

hで3行目をホールドスペースに突っ込み、Gでパターンスペースに戻します。

$ seq 1 10 | sed '3h;3d;7G'

Q4

次のコードのmainとahoの位置を入れ替えてください。

$ cat aho.cc 
#include <iostream>
using namespace std;

int main(int argc, char const* argv[])
{
	aho();
	return 0;
}

void aho(void)
{
	cout << "aho" << endl;
}

解答

mainの部分をホールドスペースに入れる→消す→ファイルの一番後ろでホールドスペースを吐き出すという流れになります。

$ cat aho.cc | sed '/int/,/}/H;/int/,/}/d;$G'
#include <iostream>
using namespace std;


void aho(void)
{
	cout << "aho" << endl;
}

int main(int argc, char const* argv[])
{
	aho();
	return 0;
}
###{}でまとめる###
$ cat aho.cc | sed '/int/,/}/{H;d};$G'
###もうちょっと厳密なやつ###
$ cat aho.cc | sed '/ main(/,/^}/{H;d};$G'
###そのままコンパイルして実行###
$ cat aho.cc | sed '/int/,/}/H;/int/,/}/d;$G' |
 g++ -x c++ - && ./a.out
aho

Q5

seq 1 10 | から始めて次のような出力を作ってください。

2
1
4
3
6
5
8
7
10
9

解答

$ seq 1 10 | sed '1~2h;1~2d;0~2G'
2
1
4
3
6
5
8
7
10
9

Q6

echo 1から始めて次のような出力を作ってください。

1
11
111
1111
11111
111111
1111111
11111111
111111111
1111111111

解答

ラベルを使います。

$ echo 1 | sed ':LOOP p;s/./&&/;b LOOP' | head
1
11
111
1111
11111
111111
1111111
11111111
111111111
1111111111
###分岐を使う###
$ echo 1 | sed ':LOOP p;s/./&&/;/1\{10\}/!b LOOP'

Q7

aというファイルをtouch等で作り、次の縛りでa1, a2, a3, …, a10というファイルをaからコピーして作ってください。縛り1と縛り2を独立した別々の問題として解き、その後縛り1,2を両方満たす解を考えてみましょう。

  • 縛り1: 使うコマンドはseq、cp、sedだけ
  • 縛り2: ワンライナー中で数字を使わない

解答

###縛り1###
$ touch a
$ seq 1 10 | sed 's/./cp a a&/e'
$ ls a a? a10
a  a1  a10  a2  a3  a4  a5  a6  a7  a8  a9
###縛り2###
$ yes | sed -n '=' | head | sed 's/./cp a a&/e'
###両方###
$ sed ':a ;p;s/./&&/;/........../!b a' <<< y |
 sed -n = | sed 's/^/cp a a/e'
###(おまけ)ファイルaをsedで作る###
$ sed 'w a' <<< "abc"
abc
$ cat a
abc

Q8

echo 1 | から始めて、あとはsedだけで次のような出力を得てください。

1
11
111
1111
11111
11111
1111
111
11
1

解答

$ echo 1 | sed ':LOOP p;s/./&&/;/1\{5\}/!b LOOP' | sed 'p;1!G;h;$!d'
1
11
111
1111
11111
11111
1111
111
11
1
Pocket
LINEで送る

【問題のみ】第27回sedこわいシェル芸勉強会

Pocket
LINEで送る

解答例はこちら

問題で使うファイル等

GitHubにあります。ファイルは

https://github.com/ryuichiueda/ShellGeiData/tree/master/vol.27

にあります。

クローンは以下のようにお願いします。

$ git clone https://github.com/ryuichiueda/ShellGeiData.git

イントロ

環境

対象とするsedはGNU sedだけに絞っています。解答例はUbuntu Linux 16.04 で作成。Macの場合はcoreutilsをインストールの上、gsedをつかいましょう。GSD系の人は玄人なので各自対応のこと。

Q1

次のechoの出力について、偶数番目の文字だけ大文字にしてください。できたら、奇数番目の文字だけ大文字にしてください。

$ echo abcdefghijklmn

Q2

seq 1 100から始めてsedだけでFizzBuzzをやってみましょう。

Q3

次の出力について、3行目を7行目の下に移動してください。

$ seq 1 10

Q4

次のコードのmainとahoの位置を入れ替えてください。

$ cat aho.cc 
#include <iostream>
using namespace std;

int main(int argc, char const* argv[])
{
	aho();
	return 0;
}

void aho(void)
{
	cout << "aho" << endl;
}

Q5

seq 1 10 | から始めて次のような出力を作ってください。

2
1
4
3
6
5
8
7
10
9

Q6

echo 1から始めて次のような出力を作ってください。

1
11
111
1111
11111
111111
1111111
11111111
111111111
1111111111

Q7

aというファイルをtouch等で作り、次の縛りでa1, a2, a3, …, a10というファイルをaからコピーして作ってください。縛り1と縛り2を独立した別々の問題として解き、その後縛り1,2を両方満たす解を考えてみましょう。

  • 縛り1: 使うコマンドはseq、cp、sedだけ
  • 縛り2: ワンライナー中で数字を使わない

Q8

echo 1 | から始めて、あとはsedだけで次のような出力を得てください。

1
11
111
1111
11111
11111
1111
111
11
1
Pocket
LINEで送る

【問題のみ】第26回シェル芸勉強会及びエクシェル芸勉強会

Pocket
LINEで送る

解答はコチラ

問題で使うファイル等

GitHubにあります。ファイルは

https://github.com/ryuichiueda/ShellGeiData/tree/master/vol.26

にあります。

クローンは以下のようにお願いします。

$ git clone https://github.com/ryuichiueda/ShellGeiData.git

環境

シェル芸を行うのはUbuntu Linux 16.04です。確認はMacのExcelやWord, PowerPointで行いました。今回は特にワンライナーにこだわる必要はありません。シェルスクリプトにしても構いません。もちろん、一般解にこだわる必要もありません。

イントロ

第26回シェル芸勉強会及びエクシェル芸勉強会

Q1

.xlsxや.docx、.pptxファイルはzipファイルです。リポジトリの中のxlsx,docx,pptxを展開し、中にどんなファイルがあるか見て、再び戻して再び.xlsxファイルとして開いてみてください。

Q2

20141019OSC_LT.pptxのスライドに何回「危険」という単語が出てくるか数えてください。画像になっているものは除きます。

Q3

20141019OSC_LT.pptxのスライドから画像を抽出して、一つのディレクトリにまとめてzipで固めてください。

Q4

20141019OSC_LT.pptxのスライドの7ページ目のテキストをスクレイピングしましょう。以下が出力の例です。

戦果(?)
初日だけで見知らぬ方のマシン3台轟沈
その他自爆者多数
Docker上で試したらホストマシン沈黙の報告
自分の本がサイト経由で1冊だけ売れた
フォロワーが1人減った
(以下、フッタ等の文字列が混ざっても可とします)

Q5

graph.xlsxの2列の数字を抜き出して端末にSSV形式のデータ(CSVのカンマがスペースになったもの)、あるいはセルの番号と値のリストとして抜き出してください。

Q6

hanshin.xlsxのシートについてQ2と同様SSV形式か、セルの番号と値のリストとして端末上に出力してください。日付のセルについては何を出力しても良いことにします。

Q7

certificate.docxファイルを開いて確認し、人の名前が入るところに好きな名前を入れてみましょう。

Q8

Q7を応用し、次のリストlist.txtで、複数の表彰状を作ってみましょう。

$ cat list.txt 
シェル芸おじさん
シェル芸野郎
変態シェル芸豚野郎
Pocket
LINEで送る

SHELQ: 怪しいシェル芸キュレーションサイト

Pocket
LINEで送る

この記事はShell Script Advent Calendar 2016 18日目の記事です。

本記事の趣旨は、今年を中心にTwitterやシェル芸勉強会上で出たこわいワンライナーを、巷にあふれるクソバイラル的なランキング形式でお届けしようというものです。人さまのワンライナーを紹介していきます。普段、自分のブログでは人のふんどしでほんだしをとる1) ふんどしを脱ぐと立派な鰹節が出現するイメージの下ネタです。ようなことはなるべくしないことにしてますが、毎年謎に盛り上がるShell Script Advent Calendarに便乗してしれっとやります。あと、先日せっかくこんなことを書いたのにまるで自分で守ってないのは、やさぐれているからです。ご了承ください。

ということで、私、上田マリ(シェルガポール在住)の「シェル芸キュレーション」をお楽しみください。

今、私は、シェルガポールからのリモートシェル芸で、いかにshelqとシェル芸ヴェンキョウカイを成長させていくかしか考えていません。この新たな挑戦と新しい働き方へのトライに、シェルシェルシェルシェル、核シェルターですね。 —上田マリ

すみません!ほんとすみません!2) かなりイキってるインタビューである https://m.newspicks.com/news/651502/body/?sentlog を参考にさせていただきました。

Ubuntu 16.04 LTSのGUI環境で、必要なものをインストールした上で動作を確認しています。しかし、何が起きても責任は負えません。

第10位 (2016年2月・微妙に危険)

$ touch + ; echo 2 * 3 | bc
5

まずは第10位。「第21回未経験者大歓迎!誰でも働けるアットホームな職場ですシェル芸勉強会」の午前の部で鳥海さんによって誘発された「こんなミス誰もしないだろシェル芸」です。

上記のような計算間違いは「ディレクトリの中に『+』と言う名前のファイルがあり、そしてbcを使う時にアスタリスクのクオートを忘れると、アスタリスクがファイルのリストに変換(+だけなので+に変換)されて『2 + 3』がbcに渡る」という、ありがちな状況でよく起こります。ありがちではありません。

このバカバカしい計算間違い体験をどうしてもしたい方は、次のようにシェルとよろしくやっててください。

mery@welq:~$ mkdir iemo
mery@welq:~$ cd !$
cd hoge
mery@welq:~/iemo$ touch +
mery@welq:~/iemo$ echo 2 * 3 | bc
5

以上、第10位でした。

第9位(2015年10月・ちょっと危険

$ echo {000000000..9999999999}

第9位は「100億個の数字をメモリに書くまでbashとお前を家に帰さない危険シェル芸」です。マイナンバーシェル芸事件3) マイナンバーに抜けがないか、みんなで仲良く襲撃検証した事件。の際、とりあえず数字を全部列挙しようとしている最中に飛び出した危険なワンライナーです。

ナニがドーなるか説明しておきます。bashは

spotlight@never:~$ echo {0..9}
0 1 2 3 4 5 6 7 8 9

というふうに、連番を略記して入力すると展開して、コマンド(この場合はecho)に渡してくれる機能があります。コマンドに展開したものを引数として渡すには・・・全部メモリの上で展開する必要があります。これを踏まえて、もう一度9位のコマンドを見てください。bashが可哀想に見えます。

このときは、bashだけでなく、次の方々が犠牲になりました。尊い。

尊い。

第8位 (2016年10月)(安全・迷惑)

$ echo 響け!ユーフォニアム | sed ':a;p;s/\(.\)\(.*\)/\2\1/;/^ム/!ba'
響け!ユーフォニアム
け!ユーフォニアム響
!ユーフォニアム響け
ユーフォニアム響け!
ーフォニアム響け!ユ
フォニアム響け!ユー
ォニアム響け!ユーフ
ニアム響け!ユーフォ
アム響け!ユーフォニ
ム響け!ユーフォニア

第8位は、@ebanさんの「響け!ユーフォニアム10段逆スライド方式シェル芸」です。ある日、上の出力のように1文字ずつずらして「響け!ユーフォニアム」という文字列を出力するだけの不毛なパズルがTwitter上で暇な人たちによって流行ったのですが、みんながワイワイ長いワンライナーを捻り出している時にしれっと氏が出したものです。

一応、ちゃんと解説をしておくと、これはsed(GNU sed)のbコマンドを用いたものです。sedの部分をsedのスクリプトファイルにしてコメントを入れると、次のようになります。

curazy@grape:~$ cat ufo.sed 
#!/bin/sed -f
                   
#aというラベルをつける。「b a」でここに戻る
:a  

#1行プリント
p

#一番最初の字を後ろにくっつける
s/\(.\)\(.*\)/\2\1/

#ムで始まらなければラベルaに戻る
/^ム/!b a

このスクリプトに「響け!ユーフォニアム」という文字列を入れると、頭の文字が「ム」になるまで同じ行に対してp(プリント)が実行されるので、上記のような出力が得られます。

実行は次のように行いましょう。

takagi@buzznews:~$ chmod +x ./ufo.sed
takagi@buzznews:~$ echo 響け!ユーフォニアム | ./ufo.sed 
響け!ユーフォニアム
け!ユーフォニアム響
!ユーフォニアム響け
ユーフォニアム響け!
ーフォニアム響け!ユ
フォニアム響け!ユー
ォニアム響け!ユーフ
ニアム響け!ユーフォ
アム響け!ユーフォニ
ム響け!ユーフォニア

ちなみに、やり出しっぺの人は

だそうです。代わりに謝っておきます。私も見たことも食べたこともありません。ファンの人たちには本当に迷惑な話です。

第7位 (2016年9月・安全)

$ banner --help

どうなるか?こうなります。

以上、ぐれさんの「コマンドに馬鹿にされるシェル芸」でした。

第6位(2014年8月他、破壊実績多数・試すな危険

$ : () { : | : & } ; : 

第6位は、すこしリリース(?)から時間が経ってしまったのでランクダウンしましたが、未だに存在感抜群のforkbombです。これをシェルに打ち込むと、なにも対策を立てる間も無くOSが死にます。

この入力の意味は「:という名前の関数を定義します。その関数は、自分自身をパイプで2つつないだものをバックグラウンドプロセスで実行するというものです。:を定義したら、さっそく実行します。」というものなので、:がひとつ実行するごとに、別の:が起動して、それらが再び:を2つ起動して・・・」と倍々になってすぐプロセスで一杯になってOSが死にます。どんどんプロセスを使うので他のコマンドも起動できず、大抵の場合シャットダウンもうまくいきません。

Dockerなら大丈夫だろうと試したらホストまで死んだという報告もあるので、試すなよ!絶対試すなよ!

第5位(2014年9月・ある意味危険

$ env x='() { :;}; echo vulnerable' bash -c 'echo this is a test'
vulnerable
this is a test

第5位は、これもちょっと古いのでランクを落としてしまった「Shellshock調査用ワンライナー」です。Shellshockは、「関数の定義を変数に代入しようとすると、関数の後ろに書いたコマンドが実行できてしまう。」というbashのバグ(と、その後の騒動)を指します。

これだけなら「ふーん」という感じですが、CGIでbashが立ち上がるようになっていると話は別です。webサーバがGETで送られてきた文字列を変数に保存しますので、そのときに文字列に仕込んだコマンドが実行されることになって非常に危険です。次の例は、騒ぎの中、私のウェブサーバに飛んできたリクエストのログです。パスワードファイルを盗み見しようとしています。

xxx.yyy.zzz.aaa - - [25/Sep/2014:08:32:26 +0900] "GET / HTTP/1.1" 302 208
 "-" "() { :;}; echo Content-type:text/plain;echo;/bin/cat /etc/passwd"

ところで、「CGIでbashが立ち上がるなんて、こんな本を書いたお前のところだけだろ」という声も聞こえて来そうなんですが、CGIスクリプトからコマンドを読んでおり、shと打つとbashが代わりに立ち上がる環境でウェブサーバが動作しているという場合、知らないうちにbashが立ち上がっていますので、ご注意ください。当然、最新のbashではこのバグは潰されています。

第4位 (2016年9月・悪用危険

H4sICBmZ4lcAA2VsZgCrd/VxY2RkZIABJgZmBhAvMcBEyIQBAUwYFBhgquCqgWpAVDMUs4I4AgwMjxvbHjdNftw4mQuodgcLUHA3SMvOEKD6XbxA1tmGHSCB3QxgNgCMjcoWgwAAAA==

これはワンライナーでなく、ワンライナーで解く対象となる暗号です。なぜかTwitter上でシェル芸暗号解読大会が開催された時に私が考えた「Twitterに実行ファイルをエンコーディングして乗っけようとして頑張ってたら乗ってしまったやつ」です。こちらのサイトからELF(実行バイナリ)を作り、それをzipやbase64で変換したものです。

次のように実行できます。

takeda@jooy:~$ base64 -d hoge | gunzip > a ; chmod +x a ; ./a
うんこ

ところでこの問題、昨日発売された、Software Design 2017年1月号に似た問題が出ています(ネタバレになったら申し訳なく)。Software Design 2017年1月号で、特集で「シェル30本ノック」というのをシェル芸勉強会周辺の方々と書きました。「ワンライナー4) いつもお世話になっている編集のYさんは、頑なに「シェル芸という言葉は使わないのです。ブームの火付け役なのに。たぶん、ブレーキかけないと暴走し出すと思ってるのではなかろうか。正解。中心に40ページ」ということで、1人じゃ無理なので、シェル芸勉強会の周りの変態さん腕利きの方々に参加を募り、Slackでチームを作ってGitHubでわーっと書いていきました。SoftwareDesignのきっちりしているところと、シェル芸勉強会の奔放なところをうまく両立できていると思いますので、ぜひご一読を。

以上、宣伝でした。

第3位(2014年8月・安全)

$ eval eval \''n='\''{1..'$(dc -e 1000vp)'}'\'' eval eval eval echo '\'\\\\\\\\\\\\\\\'\\\\\\\'\\\'\''$(('\'\\\'\\\\\\\'\\\'\''$n'\'\\\'\\\\\\\'\\\'\''*'\'\\\'\\\\\\\'\\\\\\\\\\\\\\\'\\\'\''{2..$((1000/n))}'\'\\\'\\\\\\\\\\\\\\\'\\\\\\\'\\\'\''))'\'\\\'\\\\\\\'\\\\\\\\\\\\\\\'\'';'\' | tr ' ' \\n | sort -n | uniq -u

第3位、こちらも古いんですが、あまりにも変態すぎるので未だシェル芸界隈では語り草になっている鳥海師匠の「変態素数ワンライナー」です。上のワンライナーをコピペして動かしてみてください。ちゃんと動きます。そして、安心・安全です。

cafy@upin:~$ (変態すぎてSyntaxhilighterがうまく動かないので省略) | head
2
3
5
7
11
13
17
19
23
29

ちゃんと動く以外、詳細不明です。

第2位 (2016年4月30日・そこそこ危険

$ alias eval='eval eval'
$ eval

さて第2位です。これも鳥海師匠の講義の最中に飛び出した「イーバル!イーバルイーバル!!イーバル!!!」です。「ちょっと!ちょっとちょっと!」のニュアンスで1行目を読み込み、「バルズ!!」のニュアンスで2行目を実行すると、端末が死にます。コンソールでやるとPCがシャットダウンします。ちょっと、気持ちいいです。

死ぬ原理ですが、forkbombのマイルドバージョンで、2行目のevalを実行するとeval evalに置き換わってeval evalが実行され、さらにevalが二つに分裂し・・・ということでevalがたくさんになってbashがパンクして死にます。

端末で行う場合、被害としてはその端末が落ちるだけですので、皆さんもスタバ等でドヤリングする際は、exitの代わりに

cuta@findtravel:~$ alias eval='eval eval'
cuta@findtravel:~$ eval

と打って(キーボードは強打すること)、かっこよく端末を閉じるグッドプラクティスを身につけてはいかがでしょうか。何が起きても私は責任を取りませんが。

第1位 (2016年4月・安全)

$ l='L${r}FR${l}F${l}RF${r}L' r='R${l}FL${r}F${r}LF${l}R' eval eval eval eval eval eval l= r= eval echo '$l' | { read a; b=${a%%F*}; echo "from turtle import *;speed(0);pensize(2);ms=min(screensize())*0.8;l=2*ms/(2**${#b}-1);up();setpos(-ms,-ms);down();${a}done()"; } | sed 's/L/lt(90);/g;s/R/rt(90);/g;s/F/fd(l);/g' | python

さて今回の第1位は、鳥海師匠の「ヒルベルト曲線ワンライナー」です。デスクトップ環境でお楽しみください。以下は本人による実行例です。

解説はこちらの@hexominoさんのLT資料にあります。変数に再帰的に経路を埋め込んで行って、最後にPythonに食わせて実行するという手順のようです。ワンライナーもご本人の了承を得て@hexominoさんの資料から拝借しました。

うん。わからん。

最後に

ということで、鳥海師匠の1〜3位独占で終わりました。某サイト群と違って師匠には快諾を得て書いておりますが、こうやって人のやったことでブログを書いていると、やっぱり自分の手柄は本人が自分の言葉で書いた方がいいんじゃないかなあと思ってしまいます。

師匠におかれましては、ぜひ「今日から俺はシェル芸で飯を食うんだ」とご決心いただければ幸いです。

以上。

Pocket
LINEで送る

脚注   [ + ]

1.  ふんどしを脱ぐと立派な鰹節が出現するイメージの下ネタです。
2.  かなりイキってるインタビューである https://m.newspicks.com/news/651502/body/?sentlog を参考にさせていただきました。
3.  マイナンバーに抜けがないか、みんなで仲良く襲撃検証した事件。
4.  いつもお世話になっている編集のYさんは、頑なに「シェル芸という言葉は使わないのです。ブームの火付け役なのに。たぶん、ブレーキかけないと暴走し出すと思ってるのではなかろうか。正解。

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

Pocket
LINEで送る

イントロ

こちら

問題で使うファイル等

GitHubにあります。ファイルは

https://github.com/ryuichiueda/ShellGeiData/tree/master/vol.25

にあります。

クローンは以下のようにお願いします。

$ git clone https://github.com/ryuichiueda/ShellGeiData.git

環境

今回はUbuntu Linux 16.04で解答例を作りました。

Q1

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

解答

$ dig www.usptomo.com | grep -A1 ANSWER 
| tail -n 1 | awk '{print $NF}'
157.7.203.188
$ ping -c1 www.usptomo.com | head -n 1 
| awk '{print $3}' | tr -d '()'
157.7.203.188

Q2

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

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

解答

ベタなものを載せておきます。変態的解答はウェブで。

$ a="ひらけ!ポンキッキ" ; for i in $(seq 2 $(wc -m <<< $a)) ; 
do echo $a ; a=$(sed 's/\(.\)\(.*\)/\2\1/g' <<< $a) ; done

Q3

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

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

解答

$ grep bash$ /etc/passwd | tee hoge
$ grep bash$ /etc/passwd | awk '{print $0 > "huge"}'
$ grep bash$ /etc/passwd | dd of=hohe

Q4

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

$ echo すけふぇにんけん

解答

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

Q5

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

解答

$ yes | awk 'BEGIN{a="*"}{print a;a=a"*";system("sleep 1")}' 
| xargs -I@ echo -ne @"\r" 

Q6

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

$ cat crypt 
b730a730eb30b8820a00

解答

0a00あたりがカギになります。

$ cat crypt | xxd -ps -r | iconv -f=ucs-2le -t=utf8
シェル芸
$ echo -ne $(sed 's/\(..\)\(..\)/\\U\2\1/g' < crypt)
シェル芸

Q7

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

解答

$ ( date -ud '20161029' +%s ; date -ud '20161030' +%s ) | xargs seq 
| factor | awk 'NF==2{print "@"$2}' | date -uf - 

Q8

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

%e3%82%b9%e3%82%af%e3%83%aa%e3%83%bc%e3%83%b3%e3%82%b7%e3%83%a7%e3%83%83%e3%83%88-2016-10-27-21-04-17

解答

$ 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 @ ' ' 
Pocket
LINEで送る

【問題と解答】第24回◯◯o◯裏番組シェル芸勉強会

Pocket
LINEで送る

問題のみのページはこちら

イントロ

問題で使うファイル等

GitHubにあります。ファイルは

https://github.com/ryuichiueda/ShellGeiData/tree/master/vol.24

にあります。

クローンは以下のようにお願いします。

$ git clone https://github.com/ryuichiueda/ShellGeiData.git

環境

今回はUbuntu Linux 16.04で解答例を作りました。

Q1

$ cat Q1
玉子 卵 玉子 玉子 玉子 玉子
玉子 玉子 卵 卵 卵 玉子
卵 玉子 卵 玉子 玉子 玉子
卵 玉子 卵 卵 卵 卵
玉子 卵 玉子

上のようなQ1ファイルについて、次のような出力を得てください。

玉子:5 卵:1 
玉子:3 卵:3 
玉子:4 卵:2 
玉子:1 卵:5 
玉子:2 卵:1 

解答

AWKの力技になります。力技でない方法を募集。

$ cat Q1 |
 awk '{for(i=1;i<=NF;i++){a[$i]++};for(k in a){printf("%s:%d ",k,a[k]);a[k]=0}print ""}'
玉子:5 卵:1 
玉子:3 卵:3 
玉子:4 卵:2 
玉子:1 卵:5 
玉子:2 卵:1 

Q2

次のようなテキストについて、繰り返し出てきた文字の2つ目以降を省いて出力してください。例えばQ2のファイル

$ cat Q2
へのへのもへじ

の場合、「へのもじ」が正解の出力になります。

解答

$ cat Q2 | grep -o . | nl | sort -k2,2 -k1,1n |
 uniq -f 1 | sort | awk '{printf $2}' | xargs
へのもじ
$ cat Q2 | grep -o . | awk '{if(!a[$1]){printf $1};a[$1]=1}END{print ""}'
へのもじ
$ < Q2 grep -o . | awk '{if(!a[$1]){printf $1};a[$1]=1}' | xargs
へのもじ

Q3

$ cat Q3
金 日成
キム ワイプ
金 正日
キム タオル
金 正男

というデータを、

%%
キム タオル
キム ワイプ
%%
金 正男
金 正日
金 日成
%%

というように第一フィールドをキーにして%%でレコードを区切ってください。awkを使ってできた人は、awkを使わないでやってみてください。

解答

$ sort Q3 | awk '{if($1!=a){print "%%";print;a=$1}else{print}}END{print "%%"}'
%%
キム タオル
キム ワイプ
%%
金 正男
金 正日
金 日成
%%
$ sort Q2 | rev | uniq --group=both -f 1 | rev | sed 's/^$/%%/'
%%
キム タオル
キム ワイプ
%%
金 正男
金 正日
金 日成
%%

Q4

Q4.xlsxのA1のセルには数字が書いてあります。その数字を出力してください。A4には文字列が書いてあるので余裕がある人はそれも特定してみましょう。

解答

A1のセル(数字の読み方)

$ unzip -p Q4.xlsx xl/worksheets/sheet1.xml | sed 's;</c>;&\n;g' |
 grep -o '<c.*</c>' | grep A1 | sed 's;.*<v>;;' | sed 's;<.*;;'
114514
$ unzip -p Q4.xlsx xl/worksheets/sheet1.xml | hxselect -s '\n' c |
 grep A1 | hxselect -c v
114514

A2の文字列の読み方。シートには文字列のIDが書いてあるのでこれで文字列のシートを読んで特定。

###これで6番目(0番から始まるので7番目)の文字列とわかる###
$ unzip -p Q4.xlsx xl/worksheets/sheet1.xml |
 hxselect -s '\n' c | grep A4
<c r="A4" t="s"><v>6</v></c>
###抽出###
$ unzip -p Q4.xlsx xl/sharedStrings.xml |
 hxselect -s '\n' si | awk 'NR==7'
<si><t>エクシェル芸</t><rPh sb="5" eb="6"><t>ゲ</t></rPh><phoneticPr fontId="1"/></si>

Q5

ファイルQ5について、xに好きな数を代入して各行の式を計算してください。

$ cat Q5
x + x^2
x + 1/x
x*x*x

余裕のある人は、例えばxに2を代入したければ、

$ echo 2 | ...

というようにecho <代入したい数>から始めてワンライナーで解いてみてください。

解答

例えばこれで解けます。(-2)のカッコはQ5ファイルでは不要なようです。

$ sed 's/x/(-2)/g' Q5 | bc -l
2
-2.50000000000000000000
-8

echo <数字>からスタートすると、ややこしくなります。

$ echo -2 | xargs -I@ awk -v a=@ '{gsub(/x/,a,$0);print}' Q5 | bc -l
2
-2.50000000000000000000
-8

Q6

「玉子」と「卵」の数を数えて、数が少ない方を数が大きい方で置換してください。

$ cat Q6 
卵卵玉子玉子玉子玉子玉子卵卵卵玉子玉子卵玉子玉子玉子玉子卵卵玉子卵玉子卵卵玉子卵玉子

解答

力技です。

$ cat Q6 | grep -oE '(玉子|卵)' | sort | uniq -c |
 sort -n -k1,1n | awk '{print $2}' | xargs |
 awk '{print "s/"$1"/"$2"/g"}' | xargs -I@ sed @ Q6
玉子玉子玉子玉子玉子玉子玉子玉子玉子玉子玉子玉子玉子玉子玉子玉子玉子玉子玉子玉子玉子玉子玉子玉子玉子玉子玉子

Q7

次のseq(あるいはjot等)の出力から、各桁の数字の構成が同じもの(例: 11122と22111等)を重複とみなし、除去してください。

$ seq -w 00000 99999

解答

###asortを使う場合###
$ seq -w 00000 99999 | sed 's/./& /g' |
 awk '{for(i=1;i<=NF;i++)a[i]=$i;asort(a);for(k in a){printf a[k]}print ""}' |
 sort -u
###ちょっと気の利いた方法(数字が小さい順に並んでいるものだけ残す)###
$ seq -w 00000 99999 | sed 's/./& /g' |
 awk '$1<=$2&&$2<=$3&&$3<=$4&&$4<=$5' | tr -d ' ' 

Q8

1. まず、1〜7を全て含む7桁の整数を全て列挙して、tmpというファイルに出力してください。

2. 次に、相異なる7以下の正の整数a,b,c,d,e,f,gを用いて、

abcd + efg

と表せる素数と、その時のa〜gの数字を全て求めましょう。tmpを用いて構いません。

(参考: 2011年日本数学オリンピック予選第3問から。一部改。http://www.imojp.org/challenge/old/jmo21yq.html

解答

1は力技になります。

$ seq -w 0000000 9999999 | grep -v [089] |
 grep 1 | grep 2 | grep 3 | grep 4 | grep 5 | grep 6 | grep 7 > tmp

2は、うまくwhileとfactorを使って求めます。

$ cat tmp | sed 's/./& /g' | awk '{print $1$2$3$4$5$6$7,$1*$2*$3*$4+$5*$6*$7}' | while read a b ; do echo $b | factor | awk -v n=$a 'NF==2{gsub(/./,"& ",n);print n,$2}' ; done 
2 3 4 6 1 5 7  179
2 3 4 6 1 7 5  179
2 3 4 6 5 1 7  179
2 3 4 6 5 7 1  179
2 3 4 6 7 1 5  179
2 3 4 6 7 5 1  179
2 3 6 4 1 5 7  179
2 3 6 4 1 7 5  179
2 3 6 4 5 1 7  179
...
Pocket
LINEで送る