たいちょーの雑記

ぼくが3日に一度くらい雑記をかくところ

第60回シェル芸勉強会に参加しました

参加しました

問題

Q1

echoコマンドを使わずに A=$(echo {a,b,c,d}{1,2,3,4})相当のことを実行する問題。これ進研ゼミ(難読化シェル芸)でみたやつだ!

set {a,b,c,d}{1,2,3,4}
A=$@

echo $A

setを使うと位置パラメータに展開されるので、$Aに再代入すれば良いのです。zshだと (){$A=$@} {a,b,c,d}{1,2,3,4}; echo $Aという感じに無名関数を呼べるので、引数をAに展開するようにしてえいです

Q2

秒数が3の倍数の時にアホとターミナルに出力する関数をできるだけ短く書く問題

f(){[[ "$(date +%S|awk '($1%3)==0')" != "" ]] && echo アホ; sleep 1; f}

date+%Sで現在の秒数だけ出力します。シェルの$(())で剰余を求めてもいいんですけど、09のときに8進数として壊れてしまうのでawkで計算しています。関数の最後で自分自身を呼び出して再帰しています。

Q3

/を使わず ls / / / / / / / / / /相当のコマンドを実行する問題。難読化か

: $(pwd);yes "ls ${_::1}" | head -n10 | bash

: $(pwd)$_に現在のパス展開します。$_から/を切り出してコマンドを作り出します。yesheadで10個にしてbashに渡します。

Q4

dangerファイルの中から実行してしまうとファイルを削除してしまうコマンドを探す問題。

 cat S*/*60/da* | sed 's@^@echo @' | bash | grep -nv '*'

先頭にechoをつければクォートがおかしいコマンドについては展開されます。これを利用して*がなくなってしまった行だけ取り出して終了です。これ、難読化シェル芸はechoするとすべてわかるっていうのに似ていますね。

Q5

ls -lの出力のスペースをつめる問題。ただし、ls以外の外部コマンドを使わないこと。という問題

set "$(/bin/ls -l)"; echo "${@//  / }"

短くかけたんですが、スペースが3個以上になることがあり敗北です。

Q6

figletの出力2つを受け取り、それらを横に連結する関数を作る問題。小問1は引数2つまで、小問2は引数が何個でもできるものを作ります。

なんだけどいきなり小問2から始めてしまったのでこれで

f(){ X=$(paste <(echo "$1") <(echo "$2")); shift; shift && f "$X" "$@" || echo $X }

引数をshiftで切り出しながらpasteで連結。引数がまだ残っていれば再帰してやります。なければ出力して終了です。

Q7

タイムアップ

Q8

以下のような出力が得られる変数Aを作る問題

$ echo $A
c

$ echo $A | grep a
c

なんだこれは…。

A="\033[ac"
echo $A;
echo $A | grep a

エスケープシーケンス内にaを仕込んでしまう方法を試してみました。手元のzshだとうまくいったので投稿してみたんですが、botだといい感じにならなかったですね。難しい。

LT

www.slideshare.net

今回もLTさせていただきました!yukichantの出力を画像にし、高速に詠唱する試みです。聞いてくださった皆様ありがとうございました!

おわり

今回は久しぶりの物理会場ということで、苦しんでる人が近くにいるとなんだか安心するなあという感覚がよみがえりました。次回はどうなることかわかりませんが、また参加出来たらと思います。企画運営の皆様ありがとうございました。