たいちょーの雑記

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

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

参加しました。今回も参加記として解きなおしを残しておこうと思います。
PowerShell解も余裕があればやります。

当日の配信はこちらです。

Q1

shogiファイルは以下のような内容です

香桂銀金王金銀桂香
 飛     角 
歩 歩歩歩歩歩歩歩
 歩

歩 歩
 歩 歩歩歩歩歩歩
 角 銀   飛
香桂 金玉金銀桂香

このファイルの2行目の飛が動ける範囲に×を、8行目の角が動ける範囲にを書く問題です。sedのリハビリ問題とのこと。

$ cat shogi | sed '2s/ /×/g;2s/.$/ /;3s/ /×/' | sed '7~2s/ /〇/g;s/$/         /' | awk -F '' '{if(4<=NR&&NR<=6)$(10-NR)="〇"; print}' OFS=""
香桂銀金王金銀桂香         
×飛×××××角          
歩×歩歩歩歩歩歩歩         
 歩   〇     
    〇    
歩 歩〇        
〇歩〇歩歩歩歩歩歩         
 角 銀   飛         
香桂〇金玉金銀桂香         

sedawkで〇になりうるところ決め打ちで書き換えています。ほとんど解答例として解説されたものと同じですね。

PowerShell解もやってみます。

$ cat .\shogi |%{ if($idx -eq 2 -or $idx -eq 3) { $_ -replace ' $','' -replace ' ','×' } else { $_ };$idx++} -Begin {$idx=1} |%{if($idx -eq 7 -or $idx -eq 9) { $_ -replace ' ','〇' } else { $_ }} | %{ $_ -replace '$','                 '} | % { if(4 -le $idx -and $idx -le 6) { $hoge="$_".ToCharArray();$hoge[9-$idx]="〇"; $_=$hoge -join '' }; $_ }

なが~い。方針は同じなので解説はしません!

Q2

32ビット符号付整数の上限値をggらずにどうやって知るか?という問題。いろいろありそうですね。

$ echo 'typemax(Int32)' | julia
2147483647

はい。数値系の問題とかは最近juliaを使うようになりました。便利!

PowerShell解は以下の通りですね

$ [System.Int32]::MaxValue
2147483647

やはり型があると便利な場面はありますね。

Q3

hoge.cは以下のような内容です。

#include <stdio.h>
#include <limits.h>
#include <stdlib.h>

int main(){
    printf("%d", INT_MAX);
    exit(0);
}

このファイルをコピペしただけではコンパイルできないようにしてください。という問題。学校の先生も大変だ。

cat hoge.c | sed 's/$/'"$(echo 💩| zws|tr -d \')"/

zwsを使って💩をゼロ幅スペースにエンコードし、それらを各行の末尾に追加しました。便利なコマンドですねzws

Q4

grep a / -R &が実行されたとたん、コマンドの実行を止めるようにシェルなどに細工をする問題。想定解はstty tostopのようです。知らんかった。

さて自分の解答は以下の通りです。

$ function a() { [[ "$1" == "grep a / -R &" ]] && kill -9 $$ }
$ add-zsh-hook preexec a

該当のコマンドが実行されたとき、そのシェルごとkillするフックをシェルに仕込みました。ヤバイ

Q5

PID=1な topコマンドを作る問題。

$ sudo unshare --fork --pid --mount-proc top

昔やった問題の応用ですね。docker run --rm ubuntu topとかでもよいと思います

Q6

端末のプロンプト部分をファイルに書き出す問題。つまり、$PS1をファイルに書き出すってことのようです。むずかしそう

# bash >= 4.4 
$ echo ${PS1@P}

BashのParameter Expansionの機能で再現できました。なんでもあるもんだなあ

ちなみに zshにもありました

$ echo ${(%)PS1}

そしてPowerShellではpromptで出力できますね

$ prompt

Q7

psコマンドのVSZかRSSで並び替えたとき、COMMANDの列にメッセージが出るように細工をする問題。むずかしそう

$ echo うんこ | grep -o . | nl | shuf | awk '{print "awk -F "$2" n="1000**($1+3)" &"}' > a
$ source a
$ ps u | sort -nk6,6 
USER         PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
xztaity+   20149  0.0  0.0   8756  2812 pts/4    TN   15:46   0:00 awk -Fn=1000000000000
xztaity+   20150  0.0  0.0   8756  2816 pts/4    TN   15:46   0:00 awk -Fn=1000000000000000
xztaity+   20151  0.0  0.0   8756  3040 pts/4    TN   15:46   0:00 awk -Fn=1000000000000000000

ほかの環境でも再現性があるかはわからないんですが、大きな数値を代入するawkコードをを実行することでRSSを使わせ、メッセージを仕込むことができました。ほかの文字列でもできるかは謎です

終わり

stty tostopやプロンプトの展開など、全然知らないことを知れたのが嬉しかったです。 今回も企画・開催ありがとうございました!

| ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄|
|        終        |
|    制作・著作    |
|   ̄ ̄ ̄ ̄ ̄ ̄ ̄  |
|    xztaityozx    |
|_________|
  ∧∧   ||         
  ( ゚д゚)||           
  /    づΦ