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で送る

今更ですが・・・

次回は2月11日 or 18日で調整中です。

当日の様子

午前

午後

イントロ

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

問題

こちら

まとめ

サテライト会場の様子

福岡

大阪

LT(とりあえず東京のアップされてる分)

スライドアップしたら教えてくださーい!

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,.docx,.pptxファイルとして開いてみてください。

解答

解凍すると、一つのディレクトリに収まってなく、その場にいくつかのファイルが展開されるので厄介です。ファイルの置き場所と展開する場所を分けましょう。

$ mkdir ~/tmp
$ cd ~/tmp
###tmpの下に置かずに解凍###
$ unzip ~/ShellGeiData/vol.26/graph.xlsx 
ueda@remote:~/tmp$ ls
[Content_Types].xml  _rels  docProps  xl
ueda@remote:~/tmp$ tree
.
├── [Content_Types].xml
├── _rels
├── docProps
│   ├── app.xml
│   ├── core.xml
│   └── thumbnail.jpeg
└── xl
    ├── _rels
    │   └── workbook.xml.rels
    ├── calcChain.xml
    ├── charts
    │   └── chart1.xml
    ├── drawings
    │   ├── _rels
    │   │   └── drawing1.xml.rels
    │   └── drawing1.xml
    ├── styles.xml
    ├── theme
    │   └── theme1.xml
    ├── workbook.xml
    └── worksheets
        ├── _rels
        │   └── sheet1.xml.rels
        └── sheet1.xml

10 directories, 14 files
###再圧縮したファイルも別のディレクトリに作ると事故が少ない###
ueda@remote:~/tmp$ zip -r ../hoge.xlsx ./

Q2

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

解答

$ unzip ~/ShellGeiData/vol.26/20141019OSC_LT.pptx ;
grep -o 危険 ppt/slides/slide* | wc -l
17

unzipは-pオプションで必要なファイルだけcatすることができます。ということで次のようにすると完全にワンライナーになります。

$ unzip -p ~/ShellGeiData/vol.26/20141019OSC_LT.pptx 'ppt/slides/slide*' |
 grep -o 危険 | wc -l
17

Q3

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

解答

$ unzip ~/ShellGeiData/vol.26/20141019OSC_LT.pptx ;
 zip -r media.zip ./ppt/media/

Q4

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

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

解答

$ unzip -p ~/ShellGeiData/vol.26/20141019OSC_LT.pptx ppt/slides/slide7.xml |
 xmllint --format - | grep '<a:[pt]>' | sed 's;</.*;;' |
 sed 's;<.*>;;' | awk 'NF==0{print "@@@"}{print}' |
 xargs | sed 's/@@*/\n/g' | awk 'NF' | tr -d ' '
戦果(?)
初日だけで見知らぬ方のマシン3台轟沈
その他自爆者多数
Docker上で試したらホストマシン沈黙の報告
自分の本がサイト経由で1冊だけ売れた
フォロワーが1人減った
2014/10/19
OSCTokyo/Fall2014
7

Q5

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

解答

###スペース区切り###
$ unzip ~/ShellGeiData/vol.26/graph.xlsx;
 cat xl/worksheets/sheet1.xml |
 sed 's;</row>;\n;g' | sed 's;</v>.*<v>; ;' |
 sed 's;.*<v>;;' | sed 's;</v>.*;;' | grep -v "^<"
###スペース区切り・ワンライナーバージョン###
$ unzip -p ~/ShellGeiData/vol.26/graph.xlsx xl/worksheets/sheet1.xml |
 sed 's;</row>;\n;g' | sed 's;</v>.*<v>; ;' |
 sed 's;.*<v>;;' | sed 's;</v>.*;;' | grep -v "^<"

もっとスマートに行うには、html-xml-utilsとlibxml2-utilsをインストールしてhxselectコマンドやxmllintを使います。

$ sudo apt install html-xml-utils
$ sudo apt install libxml2-utils
###番号と値のリスト###
$ unzip -p ~/ShellGeiData/vol.26/graph.xlsx xl/worksheets/sheet1.xml |
 hxselect c -s '\n' | sed 's;[^=]*=";;' |
 sed 's;".*<v>; ;' | sed 's;<.*;;'
$ unzip -p ~/ShellGeiData/vol.26/graph.xlsx xl/worksheets/sheet1.xml |
 xmllint --format - | grep -e '<c r=' -e '<v>' | xargs |
 sed 's;</v>;\n;g' | sed 's/.*=//' | sed 's/>.*>/ /'

もっと便利なツールもあるという噂ですが、とりあえず私からこれくらいで・・・

Q6

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

解答

文字列は展開したファイルのxl/sharedStrings.xmlに順番に入っています。

$ unzip ~/GIT/ShellGeiData/vol.26/hanshin.xlsx 
$ xmllint --format xl/sharedStrings.xml  | head
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<sst xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" count="18" uniqueCount="15">
  <si>
    <t>真弓</t>
    <rPh sb="0" eb="2">
      <t>マユミ</t>
    </rPh>
    <phoneticPr fontId="1"/>
  </si>
  <si>

読みのデータが邪魔なので、消去した上でリストを作っておきます。

$ unzip -p ~/GIT/ShellGeiData/vol.26/hanshin.xlsx xl/sharedStrings.xml |
 hxselect si -s '\n' | awk -F'[<>]' '{print NR-1,$5}' > strings
$ head -n 3 strings 
0 真弓
1 弘田
2 バース

次に、シートのデータを加工していきます。文字列のセルには「t=”s”」という属性があるので、これで文字列のセルと数字のセルを分けます。文字列のセルのv要素にある数字は、sharedStrings.xmlの何番目の文字列がこのセルに入るかを意味します。(sharedStrings.xmlはXMLファイルなのにデータの並び順で文字列を管理しているという・・・)

$ unzip -p ~/GIT/ShellGeiData/vol.26/hanshin.xlsx xl/worksheets/sheet1.xml |
  hxselect c -s '\n' | grep '<v>' |
 awk -F'[<> "]' '/t="s"/{print $4,"s",$(NF-4)}!/t="s"/{print $4,"n",$(NF-4)}'
B1 n 42522
C1 n 42561
A2 n 1
B2 s 0
C2 s 0
A3 n 2
B3 s 1
C3 s 9
A4 n 3
B4 s 2
...

ここまでできたら、awkで無理やり文字列のファイルとデータのファイルを混ぜて答えを出します。この例ではFILENAMEという変数を使っています。

$ unzip -p ~/GIT/ShellGeiData/vol.26/hanshin.xlsx xl/worksheets/sheet1.xml |
 hxselect c -s '\n' | grep '<v>' |
 awk -F'[<> "]' '/t="s"/{print $4,"s",$(NF-4)}!/t="s"/{print $4,"n",$(NF-4)}' |
 awk 'FILENAME=="strings"{s[$1]=$2}FILENAME=="-"&&
$2=="s"{print $1,s[$3]}$2=="n"{print $1,$3}' strings -
B1 42522
C1 42561
A2 1
B2 真弓
C2 真弓
A3 2
B3 弘田
C3 北村
A4 3
B4 バース
C4 バース
A5 4
B5 掛布
C5 掛布
A6 5
B6 岡田
C6 佐野
A7 6
B7 佐野
C7 木戸
A8 7
B8 平田
C8 平田
A9 8
B9 木戸
C9 永尾
A10 9
B10 ゲイル
C10 池田

Q7

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

解答

ホームの下にtmp等の一時ディレクトリを作ってそこで試しましょう。-iオプションは、BSD系のsedの場合-i.bakと言うように拡張子をつけてバックアップファイルを作らなければなりませんが、その場合はバックアップファイルを消してから再圧縮します。

###~/tmp/で作業すると仮定します###
$ unzip ~/ShellGeiData/vol.26/certificate.docx ; 
sed -i 's/WINNER/しぇる芸のオッサン/' word/document.xml ; 
zip -r ../hoge.docx ./
###ワーニングが出ますが開けます###

Q8

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

$ cat list.txt 
シェル芸おじさん
シェル芸野郎
変態シェル芸豚野郎

解答

unzipに-o(overwrite)オプションをつけると便利です。

$ cat ~/ShellGeiData/vol.26/list.txt | 
while read name ; do unzip -o ~/ShellGeiData/vol.26/certificate.docx ;
 sed -i "s/WINNER/$name/" word/document.xml ;
 zip -r ../$name.docx ./ ; done
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で送る

Software Design, ラズパイマガジン, システム/制御/情報

Pocket
LINEで送る

こちらでは悪質な記事を書きましたが、最近立て続けに出版があったので真面目に報告いたします。

Software Design 2017年1月号

シェル30本ノックを6ページくらい書き、あと全編にわたっていろいろ関与しました。

ラズパイマガジン 2017年2月号

日経Linuxの4-6月号の再掲です。

システム/制御/情報

システム制御情報学会の学会誌に総説を寄稿いたしました。まだWeb上に情報がありませんが、

  • 上田 隆一:
    “確率ロボティクスの歩みと将来展望,”
    システム/制御/情報, Vol. 60, No. 12, pp. 503-508, 2016.

です。著者略歴で「シェル芸」という言葉を出しました。

以上、よろしくお願い申し上げます。

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で送る

2016年10月29日(土曜日)、さくらインターネットさんで行いました。横田さんはじめサテライトの皆様、東京の参加者のみなさまありがとうございました。

大体のリンクはTogetterにありますので、ここではビデオへのリンクだけ・・・(だんだん簡略になってますが・・・)

Pocket
LINEで送る

【問題と解答】第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で送る