たいちょーの雑記

ぼくが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の出力を画像にし、高速に詠唱する試みです。聞いてくださった皆様ありがとうございました!

おわり

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

owariコマンドを実行するActionを書きました

書きました。常々CIと相性がいいんじゃないか?と思っていたんです。ということで、Actionの書き方の勉強ついでに作ってみました。

github.com

owariとは

github.com

owariは終焉にまつわるアスキーアートを出力するだけのジョークコマンドです。このブログでも何度か書いていますね。

xztaityozx.hatenablog.com xztaityozx.hatenablog.com

何かが終わったときに表示されそうなAAを出力するので、処理の長いコマンドの後に && owari とつけ足しておくと、なんだか楽しい気分になります。

その他には記事の最後とか、スライドの最後とかに使われていたりしますね。

CI/CDでもowari

CIというのはそれなりに時間のかかるものです。素早く処理させるために、キャッシュしたり、ワークフローを見直したりなど皆さん頑張っていることと思います。 owari-actionはそのお手伝いができます。

いえ、実行時間を短縮するような仕組みは一切持っていません(むしろ伸びます)。ただ、なんだか楽しい気分にしてくれます。なんだか楽しい気分にしてくれるので、実行時間が長くてもまぁいいか!となるわけですね。

使い方

いつものようにyamlに書くだけです。

name: example

on: [push]

jobs:
  example:
    runs-on: ubuntu-latest
    steps:
      - name: default
        uses: xztaityozx/owari-action@v1.0.0

      - name: owari kanban
        uses: xztaityozx/owari-action@v1.0.0
        with:
          args: 'kanban -a xztaityozx owari-action'

      - name: as job summary
        uses: xztaityozx/owari-action@v1.0.0
        with:
          as-summary: true

      - uses: xztaityozx/owari-action@v1.0.0
        with:
          args: 'kanban -a xztaityozx "これは スペースが 含まれている 文字列"'

実行結果はこんな感じです。

inputs.as-summary

trueにしておくと、workflowの詳細ページに以下のような感じのサマリーを吐き出してくれます。デフォルト値は false です

owari-as-summary

inputs.args

owariコマンドへの引数です。デフォルト値は default -a ${{github.repository}} です

outputs.content

owariコマンドの出力を outputs.content に格納しているので、owari-actionの後のstepとかでも使えます

jobs:
  example:
    runs-on: ubuntu-latest
    steps:
      - name: default
        id: owari
        uses: xztaityozx/owari-action@v1.0.0

      - run: echo ${{steps.owari.outputs.content}}

仕組み

Dockerコンテナのアクションを作るチュートリアルに従って作りました。owariのバイナリをダウンロードして引数をよしなに渡すってだけです。

簡単に作れたので良かったんですが、DockerコンテナのアクションはLinuxオペレーティングシステムじゃないとダメということなので、JSでやればよかったなって感じです。気が向いたらなおします。あと、やっぱりフォント問題でずれてるので難しいねって思います。

おわり

なんだか楽しい気分になるだけですが、よければ使ってみてください。


          糸冬
-------------------------
  制作・著作 xztaityozx

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

参加しました

午前

構造化プログラミング入門の第三回。涙の最終回です。

テーブル駆動方式とは論理分の代わりにテーブルの情報を使ってプログラムを制御するもの。 状態遷移表を素直にプログラムにする感じ。講義の途中で演習がありました。自分はC#で解答したので以下に貼っておきます。

int[,] nextState = new int[8,6]{
  {-1, 1,3, 2,-1,-1},
  {-1,-1,3, 2,-1,-1},
  {-1,-1,4, 2,-1,-1},
  {-1,-1,3, 4, 5,-2},
  {-1,-1,4,-1, 5,-2},
  {-1, 6,7,-1,-1,-1},
  {-1,-1,7,-1,-1,-1},
  {-1,-1,7,-1,-1,-2},
};

int getCharType(byte b) {
  if(b == '+' || b == '-') return 1;
  if('0' <= b && b <= '9') return 2;
  if(b == '.') return 3;
  if(b == 'E' || b == 'e') return 4;
  return 0;
}

bool IsFloat(string s) {
  var state = 0;
  foreach(var b in System.Text.Encoding.UTF8.GetBytes(s)) {
    var type = getCharType(b);
    state = nextState[state, type];
    if(state < 0) break;
  }
  if(state == -1) return false;
  if(state == -2) return true;
  return nextState[state,5] == -2;
}

var tests = new [] {
  ("", false),
    ("+", false),
    ("-", false),
    (".", false),
    ("+.", false),
    ("-.", false),
    ("+1+", false),
    ("-1-", false),
    ("+1", true),
    ("-1", true),
    ("1", true),
    ("+1.", true),
    ("-1.", true),
    ("1.", true),
    ("+.1", true),
    ("-.1", true),
    (".1", true),
    ("+1.1", true),
    ("-1.1", true),
    ("1.1", true),
    ("+1.1E", false),
    ("+1.1E+", false),
    ("+1.1E-", false),
    ("+1.1E.", false),
    ("+1.1E1", true),
    ("+1.1E+1", true),
    ("+1.1E-1", true),
    ("+1.1E.1", false),
    ("+1.1E1.", false),
    ("+1.1e+1", true),
    ("+1234567890.1234567890E+1234567890", true),
};

foreach (var t in tests) {
  Console.WriteLine("'{0}'\t{1}",t.Item1, t.Item2 == IsFloat(t.Item1) ? "OK" : "NG");
}

演習2はnextStateint[8,256]に書き換える問題でした。ここまでするとコードから状態遷移表を読み取ることができなくなる。つまり使いすぎ注意ということ。

午後

問題1

1億カラムあるファイルの 87654321 カラム目を出力する問題

$ awk '{print $87654321}' yoko

これだと遅いので後ろから読むなどすれば速いと思うので sel の後ろから読むモードで…と思ったけどラインバッファを超えて読み込めなかったです。笑っちゃうね…。

問題2

nums.gzに逆順の行番号をつける問題。

$ seq 1e8 | tac | paste - <(zcat nums.gz)

seq 1e8 -1 1も試したけどこれは遅い。stepが1の時は最適化されてるからというのをtwitterでみてなるほどなあと思いました。

問題3

nums.gzから漢数字を覗いて数値順にソートする問題。できるだけはやいと良いとのこと

zgrep '^[0-9]*$' nums.gz | split --lines=1000000; ls x*|xargs -n1 -P0 -I@ zsh -c 'sort @ | sponge @';  sort -nm x* > ans

splitを使ってファイルを分割。それぞれをいったんソートして sortマージソートするというもの。そこそこの時間で終わるのでいい感じだけど、ソートの結果あってるんかなこれ。

問題4

2020.tar.bz2を展開して出てきたファイルから

  1. 最もファイルサイズが大きいものを探す
  2. 展開せずに小問1と同じものを探す

という問題。

# 小問1
$ ls -rl --sort=none ./2020/ | awk 'max < $5{a=$0;max=$5}END{print a}'
# 小問2
$ tar -tvf ./2020.tar.bz2 | awk 'max < $5{a=$0;max=$5}END{print a}'

エントリ数がスゲーのでlsにソートさせると相当時間がかかってしまいます。というわけで--sort=noneでこれを無効に。あとはawkで最大値を探すだけです。小問2の方はtar -tvfの出力から同じことをするだけですね。

ところでいつもalias ls=exaしてるので素のlsを使おうってなったときちょっとハマります

問題5

2020.tar.bz2を展開して出てきた 2020 ディレクトリで

  1. hoge.cgiのうちhogeにあたる部分でディレクトリを作る
  2. 2020以下にあるファイルをそれぞれのディレクトリに移動させる(hoge.cgiならhogeディレクトリにmv)

という問題。

# 小問1
ls -U | sel -d. 1 | sort -u | sed 's:^:mkdir &:e'
# 小問2
fd . --type=f --max-depth=1 | rargs -j10 -p './([^\.]+).(.+)' mv {} ./{1}/

小問1はまぁはい。という感じの回答です。もしかしたら sortの前に uniqをはさんだ方が速いかもしれないです。 小問2はfdrargsで。並列化もできるしまぁそこそこの時間で終わるんじゃないかな…?

問題6

たくさんのログファイルからコマンドを数え上げる問題。LANG=Cみたいなひっかけもあるのでこれを除外しながらいい感じにしないといけないとのこと。

$ fd . --type=f | surge -P10 -- zsh -c 'read A;grep -e "^+ " $A|grep -oPe "^\++ [^ ]+"|grep -v =|sel 2|sort -u' | sort -u | fmt -1 | sort | uniq -c | sort -rn

fdですべてを列挙、surgeにファイルを渡して並列で検索!爆速!みたいなのを考えて描いたんですが愚直にgrepに全部渡す野に比べて激おそでした。まぁそうだよね。grepってよくできてるんだわ

LT

ぐれさんの teip コマンドアップデート

最強のteipコマンドに新しい機能が入ったよ。という内容のLT。めちゃめちゃ便利そうでした。

次郎さんのPEGについて

https://www.slideshare.net/jiro4989/peg-251688145

Parsing Expression Grammar(PEG)についての話でした。以前次郎さんがTwitterでつぶやいてるのを見て気になってはいた内容でした。聞けてうれしい。便利そうなので自分でも使ってみようと思います。

終わり

最終回ということでした。準備など本当にありがとうございました。演習問題があったおかげで理解もしやすかったです。テーブル駆動方式は個人的に良く書くコードにも使えそうなので試してみようと思います。

午後の部も毎回問題の整備ありがとうございます。今回はパフォーマンスをかなり意識する問題ということで、いつも通りの「うごけばええやろ」以外のアプローチをいろいろ考えられて良かったです。

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

しました

午前

構造化プログラミング入門の2回目でした。ジャクソン流構造化プログラミングについての講義で、例題に図を描いてみたりなどをしました。

配信はこちら

午後

今回はPowerShellでも解きます。問題と解答はこちら

Q1

1行目に今日の日付、3行目以降にN日後の予定が書かれているファイルがあります。このN日後を具体的な日付になおしてくださいという問題。

$ cat She*/vol.58/memo | sed 's/日後/ days@/' | awk 'NR==1{d=$2}NR>2{$1=d;print}' | sed 'y/年月日/-- /' | teip -f1 -d@ -- zsh -c "while read L;do date -d \$L +'* %Y年%m月%d日';done" | tr -d @
* 20220307日: ワクチン接種
* 20220311日: 国際ロボット展
* 20220312日: シェル芸勉強会

N日後の部分を、2022-03-05 n daysに変換、teipで日付のフィールドだけ選択して date に渡し、日付を計算させる感じです。

PowerShellでもやってみます。

$ DATE=iex 'cat .\memo |%{"$_" -split " "} | select -Index 1'
$ cat .\memo | select -Skip 2 | %{ $x="$_" -split " "; $x[1]=(date $DATE).AddDays(+($x[1] -replace "日後:","")).ToString("yyyy年MM月dd日:");$x -join " " }

Get-Dateで日付のオブジェクトが得られ、そこに生えてるAddDaysで日付を計算して出力しています。 .NETを少し触るので System.Hogeに生えてる!みたいなのはちょっとわかるんですけどPowerShell独特の書き方がまだわからんですね。

Q2

数字を使わずに date コマンドに 2022年02月22日 2 22:22:22 を出力させる問題。日付と時間の間にあるのは、火曜日を表す2とのこと

false;a=$?;true;b=$?;date --date "$(date +%Y)-$b$((a+a))-$((a+a))$((a+a)) $((a+a))$((a+a)):$((a+a))$((a+a)):$((a+a))$((a+a))" +"%Y年%m月%d日 %u %T"

無理やり。数値を終了コードから持ってきて計算を繰り返すという感じです。

$ Get-Date (Get-Date).AddMonths(-1).AddDays(7) -UFormat "%Y年%m月%d日 %u %d:%d:%d"
2022年02月22日 2 22:22:22

PowerShellの方ではtwitterに投稿された賢い方法でやりました。2022年3月15日に書いてるので、足したり引いたりする部分は当日とは違いますが

Q3

jsonyamlに変換する問題

$ cat 13.json | gron | grep line_ | sel -gd "\.|=" -D: 3 4 | sed 's/ :/:/' | tr -d \; | sed 's/line_cd/  - &/;s/line_name/    &/;1iline:' | head

yqを使えば一撃なんですが、それなしで解いてみました。必要なところ切り出して~インデントつけて~って少々面倒になっちゃいますね。やはり決まったデータ構造の変換は専用のツールに任せるのが楽ですね

$ cat .\13.json | ConvertFrom-Json | ConvertTo-Yaml

PowerShellにはpowershell-yamlというモジュールがあり、変換をえいでやってくれるので楽です。

Q4

尺取り虫みたいな動きをするうんこの動画を作る問題。しゃくとりうんこというらしい…うむ…

$ yes $(echo 💩{,,,,,,,,,}| tr -d ' ') | awk -F '' '{$(NR%10?NR%10:10)="@";print}' OFS='' | rev | awk '{for(i=0;i<NR/10;i++)printf " ";print}' | tr @ ' ' | head -n 300 | textimg -a

このワンライナーのうち、textimgの部分を外すと

 💩💩💩💩💩💩💩💩💩
 💩💩💩💩💩💩💩💩 💩
 💩💩💩💩💩💩💩 💩💩
 💩💩💩💩💩💩 💩💩💩
 💩💩💩💩💩 💩💩💩💩
 💩💩💩💩 💩💩💩💩💩
 💩💩💩 💩💩💩💩💩💩
 💩💩 💩💩💩💩💩💩💩
 💩 💩💩💩💩💩💩💩💩
  💩💩💩💩💩💩💩💩💩
  💩💩💩💩💩💩💩💩💩
  💩💩💩💩💩💩💩💩 💩
  💩💩💩💩💩💩💩 💩💩
  💩💩💩💩💩💩 💩💩💩
  💩💩💩💩💩 💩💩💩💩
  💩💩💩💩 💩💩💩💩💩
  💩💩💩 💩💩💩💩💩💩
  💩💩 💩💩💩💩💩💩💩
  💩 💩💩💩💩💩💩💩💩
   💩💩💩💩💩💩💩💩💩
   💩💩💩💩💩💩💩💩💩
   💩💩💩💩💩💩💩💩 💩
   💩💩💩💩💩💩💩 💩💩
   💩💩💩💩💩💩 💩💩💩
   💩💩💩💩💩 💩💩💩💩
   💩💩💩💩 💩💩💩💩💩
   💩💩💩 💩💩💩💩💩💩
   💩💩 💩💩💩💩💩💩💩
   💩 💩💩💩💩💩💩💩💩
    💩💩💩💩💩💩💩💩💩
    💩💩💩💩💩💩💩💩💩
    💩💩💩💩💩💩💩💩 💩
    💩💩💩💩💩💩💩 💩💩
...

10行ごとにインデントが深くなるしゃくとりうんこが出力されます。2つのawkでできていて、前半はしゃくとり動作、後半はインデントを頭につけるものですね

$ $NR=0;[System.Linq.Enumerable]::Repeat([System.Linq.Enumerable]::Repeat('💩', 10) -join " ",30) |%{$x="$_" -split " ";$x[$NR%10]=" ";[array]::Reverse($x);" "*[Math]::Floor(($NR/10))+($x -join "");$NR++}

PowerShellでも同様の指針です。$NR/10が四捨五入されるというのにハマってしまったのでPowerShellむずい…ってなりました

Q5

危険シェル芸なのでスキップ

Q6

file1file2から似た文字列のペアを作る問題。

join -j9 She*/vol.58/file* | while read L R; do echo $L $R $(echo $L | grep -o . | sort | diff - <(echo $R | grep -o . | sort) | wc -l); done | sort -nk3 | head -n4 | sel 1 2

方針としてはなんちゃって編集距離を計算して、距離が近いもの同士をペアにするというものです。単語を分解してソート、diffを取って出力行数を編集距離とし、出力します。これをすべてのペアで行い、小さい順に取り出すという感じです。

$ cat .\file1 | Join-Object -RightObject (cat .\file2) -JoinType Cross |%{ @{x=$_;c=(diff ($_[0] -split "" | sort) ($_[1] -split "" | sort)).Count} } | Sort-Object -Property c | select -First 4 |%{$_.x -join " "}

PowerShellでも同じ方針にしてみました。Join-ObjectはJoinModuleで入手できます。

Q7

めちゃデカファイル nums.gz には数値がたくさん書いてあるので、その合計を計算する問題。

$ (zgrep '[0-9]' nums.gz ;zgrep -v '[0-9]' nums.gz | numconv) | awk '{s+=$1}END{print s}'

時間中に解けなかったので解説通りの解で。zgrepに与える正規表現^[0-9]*$にしたら一生終わらなかったので最小にしてみました。処理時間が話題になっていたので自分でも測ってみると

11.78s user 1.30s system 80% cpu 16.251 total

でした。PowerShellのほうはzcat相当のことをやるのがめんどくさかったのでやめときました

LT

今回もLTさせていただきました!

www.slideshare.net

今回はsurgeというコマンドを作りましたという話をしました。「行を列に変換し、任意のコマンドのSTDINへ流し込み、その出力を行に戻して出力する」というものです。while read L; do ... doneのショートハンド的なコマンドですね。while read L;do ... doneだとパフォーマンスが残念なこと、コマンドを適用したいだけなのにそれ以外の部分の分量が多くてつらいことが気になっていたので作ってみました。

そのうち個別の記事でも書きたいと思っています。

ちなみに surge を使って以下のように書けば

$ (zgrep '[0-9]' nums.gz ;zgrep -v '[0-9]' nums.gz | numconv) |  paste -{,,,,,} | surge -P 20 -- awk '{s+=$1}END{print s}' | awk '{s+=$1}END{print s}'

Q7を並列で計算させることもできるんですが、むしろ遅くなるので適材適所って感じがしますね。

おわり

今回もとても楽しかったです!次回は自分の気になる話があるのとことだったので今から楽しみです。企画・開催ありがとうございました!

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

参加しました

今回は午前もありました

午前

今回は久々に午前がありました。配信はこちら。構造化プログラミングシリーズの1回目。 ダイクストラ大先生の言ってることを理解するにはGotoだらけのプログラムを書くと良いとのことで、状態遷移図とそれを途中まで実装したプログラムを埋める実習などで説明されました。 詳しいことは配信のアーカイブを見ればよいので書きませんが…。

オートマトンは昔少しだけ勉強したんだけど、GoToで書かれていれば読みやすいか?と聞かれるとそうかしら…?と思ってしまった。あんまり慣れてないからかな…?今度試してみようと思います。

午後

今回もzshのみ。PowerShellで解いてもいいけど体力が0を超えて-100になるので…。

配信はこちら

Q1

reiwaファイルから 令和 を数え上げる問題。

$ cat Sh*/vol.57/reiwa | uconv -x NFD | grep -o 令和 | wc -l
20

実はコードポイント違いの令が存在するので、それに騙されないようにする問題。ここではuconvユニコード正規化して数え上げる感じにしました。

Q2

kanji2ファイルの旧字体新字体に変換する問題。

$ curl http://www.gaoshukai.com/lab/0039/N_O_character.txt > o
$ cat Sh*/vol.57/kanji2 | while read L; do echo $L | grep -o . | while read R; do grep $R ./o 2>/dev/null || echo $R; done | awk '{print $1}' | paste -sd ''; done
写真
星図
学校
鉄道
鉄砲弾
灯台
両腕

インターネットに転がっていた辞書ファイルを使ってgrepで新旧を入れ替えてます。

Q3

kanjiファイルから日本語にない漢字を取り出す問題。

$ cat Sh*/vol.57/kanji | uniname | grep Unknown | awk '{print $7}' | paste -sd ''
无产阶级简华历场协议

uninameで調べたら日本語にない漢字はUnknownで絞り込めることが分かったのでそれを利用しました。

Q4

繫体字を簡体字にする問題。

$ cat Sh*/vol.57/ho* | hanzi-convert -s -

hanziconvが便利です

github.com

Q5

以下のような./a.shを作って

#!/bin/bash

date
sleep 30
date

1つ目と2つ目のdateの間を40秒以上にする問題。

$ ./a.sh &;x=$!;sleep 1s;kill -STOP $x;sleep 40;kill -CONT $x

killで止める案を見て良いな~と思ったので採用しました。

Q6

echo うんこ > unkoをしてからgrep うんこ unko | cat >> unkoを繰り返しているといつしか止まらなくなるので、これを止める問題。

$ echo > unko

unkoファイルを空にしてしまえば止まります。

Q7

因数分解する問題。どういう…どういうことなのですか…

$ echo 'factor(x^8 - y^8);' | maxima

Maxima 5.43.2 http://maxima.sourceforge.net
using Lisp GNU Common Lisp (GCL) GCL 2.6.12
Distributed under the GNU Public License. See the file COPYING.
Dedicated to the memory of William Schelter.
The function bug_report() provides bug reporting information.
(%i1)                                          2    2    4    4
(%o1)                - (y - x) (y + x) (y  + x ) (y  + x )
(%i2) %

maximaというツールがあるのでそれでやると楽とのこと。いろんなツールがあるんだなあ…

Q8

循環小数である7/17の最短の循環部分を求める問題。

$ echo -e 'scale=60\n7/17' | bc | grep -oPe '(\d+?)\1' | head -n1 | awk '{print substr($0,0,length($0)/2)}'
4117647058823529

正規表現でひっかければ良い。こういう時後方参照がさっと扱えるようになると楽ですよね~。

LT

今回もLTしました。

www.slideshare.net

12月ということでまたナベを使って何かしました。なんだこれは…。

おわり

今回もとても楽しかったです!午前回があると学びがさらに多くて良いですね…!次回も楽しみです。企画・開催ありがとうございました!

シェル芸160ノック29

9月末に発売されたシェル芸本の続きです。

gihyo.jp

前回はこちら

xztaityozx.hatenablog.com

問題156

$ echo gihyo.jp github.com gitlab.com wikipedia.org | fmt -1 | while read fqdn; do [[ "$(nslookup $fqdn | awk '/Non-authoritative answer:/,0' | grep -Pe 'Address: \d+\.\d+\.\d+' | wc -l)" -gt 1 ]] && echo $fqdn; done
gihyo.jp

問題157

$ sudo tcpdump -x -c 1 icmp 2>/dev/null | grep 0x00 | sel --remove-empty 2: | fmt -1 | awk '/0800/,0' | awk 'NR>=4'

問題158

$ ping gihyo.jp | grep -m1 -oP "(?<=ttl=)\d+"
56
$ sudo traceroute -I gihyo.jp | awk 'END{print NR-1}'
10

問題159

$ cat qdata/159/sites.txt | while read D;do whois $D | grep "No entries" && echo $D >> fake_sites.txt; done

問題160

$ echo | openssl s_client -showcerts -connect example.com:443 |& openssl x509 -noout -dates |& grep not
notBefore=Dec 10 00:00:00 2021 GMT
notAfter=Dec  9 23:59:59 2022 GMT

この有効期限を端末で表示出来たら便利そうですね。

ホンマか?

完走した完走

完走した感想です。 めちゃめちゃいろいろ勉強になりました。普段シェル芸勉強会でやるような問題はさっと解けることもあるのですが、ファイルシステムやネットワークの話とかになるとそうもいきませんでした。そういった部分はまたもう一度解こうと思います。とても楽しかったです。ありがとうございました。

シェル芸160ノック28

9月末に発売されたシェル芸本の続きです。

gihyo.jp

前回はこちら

xztaityozx.hatenablog.com

問題151

$ curl http://file.ueda.tech/eki/l/11302.xml > a
$ cat a | grep -Pe "lon|lat|name" | sd '<[^>]+>' '' | awk '{print $1}' | xargs -n3 | while read D E F; do echo $D $(curl "https://cyberjapandata2.gsi.go.jp/general/dem/scripts/getelevation.php?lon=$E&lat=$F" | jq -r '.elevation'); sleep 1s; done

問題152

$ while true; do command wget localhost:8000/index.html  |& grep 200 &> /dev/null && echo Success || echo Warning; sleep 1s; done
Success
Success
Success
...

問題153

$ (echo -e "HEAD / HTTP/1.1\nHost: www.google.co.jp\n\n";sleep 1s) | telnet www.google.co.jp 80

問題154

$ echo wget curl ping dig nslookup | fmt -1 | while read CMD; do sudo strace -f $CMD google.com |& grep /etc/hosts && echo $CMD; done

問題155

$ echo -n test > index.html&&python3 -m http.server
$ curl localhost:8000 -v
*   Trying 127.0.0.1:8000...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 8000 (#0)
> GET / HTTP/1.1
> Host: localhost:8000
> User-Agent: curl/7.68.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
* HTTP 1.0, assume close after body
< HTTP/1.0 200 OK
< Server: SimpleHTTP/0.6 Python/3.9.0
< Date: Tue, 21 Dec 2021 12:52:52 GMT
< Content-type: text/html
< Content-Length: 4
< Last-Modified: Tue, 21 Dec 2021 12:52:51 GMT
<
* Closing connection 0
test

$ (echo -e "HTTP/1.1 200 OK\nContent-Length: 5";echo -en "\ntest") | nc -N -l 8080