Goが面白いのでまたcdx作った
cdx
cdx
は僕が一人でメンテしてる cd
コマンドのラッパーです。この手のツールでよく使われているのは、enhancd
やz
などがあります。
とくにenhancd
は非常に強力なツールで、利用している方も多いと思います。
cdx
ではCustomSource
という設定項目を用意しました。これを利用することでenhancd
の持つような機能はユーザー側が設定として与えることが出来ます。そのかわりcdx
は僕が素の状態である程度使えるような機能だけを実装したものになります。
要求環境
- Go lang (v1.10.2 以上)
- 実装にはGoを使いました。最近はじめて面白いなと思いました。CLIツールを作るならGoはいい感じですね
- bash or zsh
- fishは対応していません
- fzfやpecoみたいなFuzzy-Finder
インストール
go get
するか、GitHubのReleaseページからバイナリをダウンロードしてパスの通ったところに置いてください
$ go get github.com/xztaityozx/go-cdx
- お好みのFuzzy-Finderを用意します。個人的には
fzf
がすきです。fzy
と言うやつもいいらしいですね
- コンフィグを書いて置きます
$ mkdir -p ~/.config/go-cdx $ cat << EOF > ~/.config/go-cdx/.go-cdx.json { "HistoryFile": "~/.config/go-cdx/history.json", "BookMarkFile":"~/.config/go-cdx/bookmark.json", "Command":"pushd", "NoOutput":true, "Make":false, "CustomSource":[], "FuzzyFinder":{ "CommandPath":"選んだFuzzy-Finder", "Options":[] }, "BinaryPath":"go-cdxへの絶対パス。go getした場合は消してOK" } EOF $ vim ~/.config/go-cdx/.go-cdx.json # 好きなように設定してください
設定値はGitHubのREADMEに書いてあるのでそちらを見てください
cdx
をロードします。
# cdxをロード $ eval "$(go-cdx --init)" # シェル起動時に自動でロードするならrcに記述すればOK $ echo 'eval "$(go-cdx --init)"' >> ~/.zshrc # or ~/.bashrc
使い方
cdx [-A,--action [act]| --add| -b,--bookmark| --config [configFile]| --cs-list| -c,--custom [name]| --help| -h,--history| --init| --make| --no-output| -p,--popd| -v,--version] [PATH]
基本はcd
コマンドと同じように使います
$ cdx ~/ # change to home $ cdx ~/Utils # change to ~/Utils
-A,--action [act]
このオプションでは移動した後にそのディレクトリで実行するコマンドを指定できます
$ cdx ~/Utils --action "ls" go-cdx go-cdx.v1.0.13 go-cdx.v1.0.13.tar.gz ... $ pwd /home/xztaityozx/Utils
コマンドはbash -c
に渡されて実行されることに注意してください
--add
ブックマークにカレントディレクトリを追加します。重複のチェックをしないので注意してください
-b,--bookmark
bookmarkからFuzzy-Finderを使って1つ選択し、cd
します。
$ cdx -b > 3/3 > [ 3] /path/to/hoge [ 2] /path/to/fuga [ 1] /path/to/foo
--config [configFile]
デフォルトのコンフィグの代わりになるコンフィグファイルを指定できます。デフォルトは~/.config/go-cdx/.go-cdx.json
です
--cs-list
後に説明するCustomSource
からのcd
の一覧を表示して終了します
-c,--custom [name]
Goでcdx
を書き直すにあたって、追加した目玉機能です
cdx
は複雑な機能を単体で持ちませんが、代わりにユーザーが機能を自由に追加することが出来ます。これをCustomSource
とよんでいます
CustomSource
は、その 名前 と Fuzzy-Finderに与える入力 のペアで構成されます。
{ "CustomSource":[ { "Name":"g", "Command":"ghq list | xargs -n1 -I@ echo 'echo -e \"$(basename @) $(ghq root)/@\"'|bash|column -t" }, ] }
この例では、 ghq list
で表示されるリポジトリ一覧から1つ選んでcd
するg
という名前の機能を追加しています
# Fuzzy-Finderに与える入力 $ ghq list | xargs -n1 -I@ echo 'echo -e \"$(basename @) $(ghq root)/@\"'|bash|column -t "Contest /home/xztaityozx/.ghq/github.com/xztaityozx/Contest" "cdx /home/xztaityozx/.ghq/github.com/xztaityozx/cdx" "dotfiles /home/xztaityozx/.ghq/github.com/xztaityozx/dotfiles" "nandokuka /home/xztaityozx/.ghq/github.com/xztaityozx/nandokuka" "yov /home/xztaityozx/.ghq/github.com/xztaityozx/yov" # cdx のCustomSource gを使ってみる $ cdx -c g > 19/19 > Contest /home/xztaityozx/.ghq/github.com/xztaityozx/Contest cdx /home/xztaityozx/.ghq/github.com/xztaityozx/cdx dotfiles /home/xztaityozx/.ghq/github.com/xztaityozx/dotfiles nandokuka /home/xztaityozx/.ghq/github.com/xztaityozx/nandokuka yov /home/xztaityozx/.ghq/github.com/xztaityozx/yov
この機能を使って、Fuzzy-Finderで選択された行のいちばん後ろのカラムが、移動先のパスとして選択されることに注意してください
CustomSource
でオレオレcdx
を作ることが出来ます
--help
ヘルプを出力して終了します
-h,--history
履歴をFuzzy-Finderで選択してcd
します。ログアウトしても履歴はリセットされません
--init
cdx
をロードするときにのみ使います
--make
移動しようとする先が存在しないディレクトリだった場合、作成するか訪ねます。yesと答えた場合のみ、ディレクトリを作成しcd
します
--no-output
cdx
からの出力を無効化します。Fuzzy-Finderや--action
出力は表示されます。
-p,--popd
popd
を実行して終了します
-v,--version
バージョン情報を出力して終了します
終わり
cdx
をよろしくお願いいたします
ICPC2018国内予選に参加した
参加しました
参加しました
A,Cの2完でした。
イカれたメンバー紹介
- ぼく(@xztaityozx_001)
- wheson(@wheson)
- 実質水色の緑。笑顔が素敵。
vim
のDockerfileを試して、dotfilesを更新したのに反映されない!って怒ってたけどpushしてなかっただけの悪いやつ
- eliza0x(@eliza0x)
- いつもはHaskellで参加してるヤツ。感情がすぐに無になる
- 激しい憎悪によって目覚めた伝説のバトルメイド2
ICPC2018国内予選0問題「参加」
すっごいあめだったので、ぜんじつ、おうちに、かえれませんでした
ちかくにそぼのいえがあるので、ひなんしました。
あさおきたら、あめがやんでいませんでした。ぬれながらがっこうにいきました。
がっこうについたら、むわっとしていました。さいあくでした
そうこうしていたら、めんばーがしゅうごうしたので、ACしました
準備
正直服とか靴とかびしょびしょでコンディションは最悪。それでもなんとか参加できそうであったので、PCのセットアップ、ホワイトボードや飲み物の用意をしました。この日、僕は家に帰れないことが確定していたため、手持ちの服を温存するために、メイド服を着ました。これは去年の11月にゼミ内の圧力により手に入れた暗黒の力です。面倒なことにこれを着ている間は「メイド長」という別の人格が宿る設定なので、色々手間です。この記事ではこの設定が守られない箇所があります。よろしくおねがいいたします。
これについてもう少しあって、正直ぼくはメイドさんという属性は好きだし、手持ちのメイド服もフリフリしててかわいいんですが、できれば誰も見ていないところでひっそり自分だけで楽しみたいと思っています。
因みにもう一着あるのですが、それはeliza0xが着ていました。
なのでここから先は二人のメイドと男が競プロしてる情景を思い浮かべながら読んでください
開始〜A問題AC
開始と同時に前回の教訓を活かしてALLを3部印刷しました。ステープラーで3部をまとめましたが、途中でステープラーがぶっ壊れて泣きました。
Aを読んでいたwhesonとeliza0xが「やるだけ」と言っていたので、また自明に実装の早いwhesonが実装しました。
ACまで10分ぐらいだったのでいい感じだと思いました。
B,Cを読む
Bをeliza0xとwhesonで考察しました。日本語が難しかったので、読解に時間がかかりましたが「実装激重だけどやるだけ」という感じだったのでeliza0xが実装することに。この間 ぼくはあとの問題のためにテンプレを作り、Cを先に読んでいました。
Bの実装が始まったのでCについてwhesonに説明しました。すると「しゃくとりするだけでは?」みたいな提案を受けたので、「109^ だけど大丈夫か?」と聞きました。なんやかんや話してみましたが、まぁ大丈夫でしょwとなったので愚直なしゃくとりを書く方針になりました。
Bがバグる。Cを通す
Bが激重だったのでバグってしまいました。「バグったら印刷して交代」という作戦を取ることにしていたので、Cをやることに。実装がちゃんと降りてきていたみたいなのでwhesonに任せました。
この辺から暑くてメイド服は半脱ぎ状態でした。
しゃくとり自体はすぐかけたみたいなのでテストケースを回すと、計算が終わらないので最適化オプションをつけると、ビビるぐらい計算がはやくなってみんなでビビりました。サンプルはあっていたので提出しAC
無限
ここからBの実装に無限にやられてしまいました。こんがらがってしまった時点で別の誰かが実装を最初からするほうが良かったのかもしれません。
eliza0xからのヘルプに答えつつ、残りの問題で解けそうなのが無いかwhesonと探しましたがぼくは最大流の波動を感じませんでしたし、DPのwhesonもどうやっておとせるかわからないということでした。
G問題が構文解析だったので構文解析のeliza0xに問題概要を説明すると「めっちゃムズいやつやん」と悲鳴をあげていました。
このあとPCのグラフィックドライバがぶっ飛んだり、雨が強くなったり、暑すぎてメイド服をやめたりといろいろありましたが、結局Bを通すことができませんでした。
まとめ
模擬では良い結果を出せただけに、今回の2完は少し悔しいものとなりました。ぼくとwhesonは今年が最後のICPCでしたが、eliza0xはまだ参加できるので、来年の活躍を楽しみにしつつ消えることとします。
第36回シェル芸勉強会@限界キャンパスサテライトを開催した
この限界のはてに、まだ救いがあると思っている
お前が生まれたこの世界は、お前を救ってくれるとまだ信じている
なんかこんな感じのことをメタルギアで聞いた気がする。
震源+大雨=限界
弊キャンパスは直近の地震で震源の真上ぐらいにあったところです。ここにこの間の大雨を合わせるとまさに限界!という感じです
大阪サテライトがこの雨の影響で中止となってしまったため、家に変えることも出来ないぼくはこの限界キャンパスで勝手にサテライトを開催することにしました。
明日大阪サテライト参加できそうにないので震源&&豪雨地帯サテライトを開催したいんですがいいですか #シェル芸
— たいちょー (@xztaityozx_001) 2018年7月6日
echo-sd 限界キャンパスサテライトは開催します!!#シェル芸
— たいちょー (@xztaityozx_001) 2018年7月6日
こちらシェル芸勉強会@限界サテライトです。見えてますとても楽しみです。#シェル芸 pic.twitter.com/fy26Jl87Yq
— たいちょー (@xztaityozx_001) 2018年7月7日
あーたのしい
午前の部
鳥海さんによる文字コード
の講義が始まりました。難読化クラスタとしては何かネタが転がっているかもしれないとワクワクしていました。
まずはlocale
やiconv
のような文字コードなどに関わってきそうなコマンドについてでした。
ずっと「ja_JP.utf8
ってなんやねん冗長やなオイ」って思ってたんですが、どういう意味なのか解ることが出来てよかったです。
locale -k LC_MESSAGES#シェル芸
— たいちょー (@xztaityozx_001) 2018年7月7日
これかんどうしている
そのあと基数変換の話題ではbash
の$((2#bbbb))
というパターンで変換できると知り驚きました。これすごい便利
いよいよ文字コードっぽいところに来た時、続きは次回ですとなっりました。えっ次回も参加するしか無い
昼休憩
昼休憩の間に限界サテライトからLTの配信が出来ないかどうか試していました。手伝ってくれた方々ありがとうございました。
限界サテライト側の機材不足で、音声がクリアに拾えないという問題があったため、結局配信は無しということになりました。悔しい・・・
昼飯を食ったあとは完全に体力の限界という感じでした。でも家に帰る手段も無いのでこのまま午後も見ることにしました。あとこれは秘密ですが、気づいたらメイド服を着ていました。
ズボンの中が最悪なのでね。スカートをはいています。フリフリがかわいいです pic.twitter.com/XlvuCQ7JMC
— たいちょー (@xztaityozx_001) 2018年7月7日
午後の部
とっても楽しい問題の始まりです。今回は時間内に解けた問題が全然ありませんでした。チクショー
因みに問題と解答はここです
問1
welcome.txt
というファイルに仕込まれたバイナリを解析して、AAを見つける問題。いきなりヘビー過ぎて泣いた。とりあえずxxd
してみると不思議な模様があったので目を細めて見てみると0x00
が紛れていたので、sed
してみました
するとめちゃめちゃなAAが出てきたので、適当にターミナルの横幅を動かしてみると70ぐらいだと解りました
cat welcome.txt | sed 's/\x00/@/g' | fold -70
因みに幅が70だったのは、toilet
コマンドの出力の幅が70だったからだそうです。なるほどな〜〜〜〜
問2
フォーマットがめちゃくちゃなファイル名を揃える問題。こういうのはよくありそうだし、できると最高かもしれないですね
これはゴリゴリやればいいなとおもったので、ゴリゴリ。
ls -1|nkf -Z|sed 's/[0-9]/& /g;s/[aA-Z]/ & /g'|sed -r 's/^([0-9]).*([aA-Z])[^組]/\1年\U\2組/g'|sed 's/組組/組/g'|paste <(ls -1) - | xargs -n2 echo "mv" | bash
まずsed
で年次と組を分離し、その後またsed
しました。ちょっと冗長ですねこれ
因みに、ぼくは全角英数と半角英数が混ざっていると死にます。
問3
2018年の日付のうち2,3,5,7
が4つ含まれる日付を列挙する問題。 例えば2018/07/23
と言った感じ。
4つあるかどうかgrep
やtr
で削ったあとawk
でlength
を見ればいいなと思っていたんですが、日付の列挙がうまく出来なかった・・・
時間内には解けなかったんですが、dateutils.dseq
というコマンドがあるよということだったのでそれを使って解いてみました。
dateutils.dseq 2018-01-01 2018-12-31|sed -E 's/[^2357]//g'| paste - <(dateutils.dseq 2018-01-01 2018-12-31)|awk 'length($1)==4{print $2}'
paste
を使えるようになってから、よく使うようになりました。とっても便利ですよねこのコマンド
問4
tanzaku
ファイルをcat
すると・・・
$ cat tanzaku ┏ ーー-┷-ーー┓ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┗ーーーーーー┛
このように表示されるのでこの中に俳句を入れる問題。ゴリゴリでいけそう
┏ ーー-┷-ーー┓
— シェル芸bot (@minyoruminyon) 2018年7月7日
┃ らおた ┃
┃ せうの ┃
┃ てちむ ┃
┃ にか ┃
┃ から ┃
┃ え ┃
┃ ┃
┗ーーーーーー┛ https://t.co/dUnDHHliqE
字余りするところは全角スペースで埋めてtetayoko
。そのあとはsed
の後方参照をつかってそれーという感じ。見た目ほど難しくなかった
問5
cowsay
コマンドの出力を右向きにする。ただし文章はひっくり返しちゃダメ。
見た瞬間うっとなるのは響け!ユーフォニアム問題に似たものを感じる。
これは最初にrev
したあとsed
で行を選択して末尾にスペースを埋め込んでいく戦法を考えました。でもあんまりよくないし何よりもめんどくさいので脳を休めてた。
問6
seq 20
のうち素数である番号を○で囲む問題。
1 ② ③ 4 ⑤ 6 ⑦ 8 9 10 ⑪ 12 ⑬ 14 15 16 ⑰ 18 ⑲ 20
こういう感じですね。午前でやったことを活かして行こうと思い。まず②のxxdを見る。ASCIIコードを見つけて、それを基準に差分を足していけばいいのでは?と思ったのでゴリゴリしてみる
seq 20|factor|awk 'NF==2{print $2}'|xargs -I@ echo "echo \$((0xe291a1+@-2))"|bash|bc <(echo "obase=16") |tr '[A-F]' '[a-f]'|sed 's/$/0a/g'|xxd -p -r|paste <(seq 20|factor|awk 'NF==2{print $2}') -|awk '{print "s/^"$1"$/"$2"/g"}'|sed -f- <(seq 20)
前回のシェル芸勉強会で覚えた-f-
も使えたので良かった。ちょっと冗長なので、他のシェル芸人さんみたいにスマートなやり方も鍛えていきたい
問7
text
というファイルには見えない文字が含まれているらしい。どこにどんなのがあるか調査する問題。
調査するというのが難しかったので、とりあえずどんなのがありそうなのかbat
で見る。すると・・・
batコマンドで丸見えだ pic.twitter.com/rDqR87EqN7
— たいちょー (@xztaityozx_001) 2018年7月7日
丸見えになったのでコレで良いのではとなってしまった。この辺でもう脳が死んでたのでこんな解答しか出来なかった・・・
問8
最後はルビをふる問題。シェル芸人からの挑戦状を読んでいたので、sed
で送り仮名を削りつつ、ルビのペアを作るのは出来てたけど上につける時のスペースの入れ方がわからなくてダメだった。
column -t
でいいよということだったので覚えていきたい。
LTしたかったやつ
都合でいつものパワポテーマで作れなかったんですが。また難読化でLTする予定でした。今回は日夜手で難読化しているシェル芸人さんたちのために難読化コンバータを作りました。Go製です。ぜひ使ってみてください
因みにぼくは使ったことないです
まとめ
シェル芸勉強会はやはりサテライトでみんなで集まってやるのがたのしいですね。一人でサテライト開いても寂しいだけでした。問題が激しかったので寂しがっている暇はありませんでしたが。次回も参加したいなーとおもっています
今回もとても楽しかったです!ありがとうございました!!!
ICPC2018国内模擬に参加しました
参加した
参加しました
ABCEの4完でした。
イカれたメンバー紹介
- ぼく(@xztaityozx_001)
- wheson(@wheson)
- 実質水色の緑。紅茶が好きらしい
vim
のDockerfile試しておいてって頼んだのにスルーした悪いヤツ
- eliza0x(@eliza0x)
敬称略します
準備
僕の研究室を会場にすることになったので、PCのセットアップをした。僕以外の二人がUS配列を使う人たちだったので、Fcitxの設定を色々した。
エディターはvim
で良いだろうとなったので、設定ファイルをかき集めてシンボリックリンクを貼り直すようなスクリプトでも作っておくか〜と思ったけど、Dockerでいいじゃんとなったのでそっちを用意した。
どのターミナルが誰のvim
かわからんみたいになったので、ノード名を変えるとかしたほうが良さそう
直前にプリンターが死んだけど気合で直した。えらい
開始〜A問題ACまで
とりあえず全部印刷して、A,B,Cをざっくり見た。whesonが「Aはやるだけですね」と言ったので自明に実装が早いwhesonにまかせてB,Cをeliza0xと読むことにした。
Cを読んでいたらBNFが見えたので、eliza0xに投げた。ワクワクして「やるだけですね」と言ってた。
Bを読んでいたeliza0xが条件を式にしてくれていたので、ほぼ読んでないけど書けそうになった。
そうこうしているうちにwhesonがAを通した。ここまででだいたい15分だった。
D,Eの考察とCの実装
eliza0xが先にC行けそうなのでやりたいとすごいやる気だったので譲った。その間Dをwhesonと眺めることにした。
各桁にはコレだけ目的の数があるよね〜〜って式を立ててたんですが、ホワイトボードで列挙して数え上げたときと誤差がでて死亡。任意の2つの数字の組み合わせで、小さい順に並べると二進数っぽい増え方するよね〜って言ったりしていたけど、ダメそうだったのでEを先に見ることに。このときeliza0xは半分ぐらいCが出来ていたっぽい
これは失敗だが、3部問題を印刷しなかったので、全員が一度に問題を見れなかった。なので先にwhesonにEを読んでもらった。
whesonが「グラフですね」というのでイヤだなーと思っていたが、条件を聞くと二部グラフの波動を感じたので言った。whesonも少し考えた後、目を大きく見開いてそうですねといっていたので、ほぼ考察終了。このときの彼の顔がまさにピンときたみたいな顔だったので忘れられない。
「ホンマに二部グラフなんか」と思ったので条件を再度精査して、ホワイトボードに書き起こす。そしたら二部グラフ丸出しだったので、そうっぽいということになった。
ライブラリの所有者で実装が完全に頭で出来ていたwhesonがEを書くと言っていたので、僕はBを脳内コーディングして、Cを待つことに。
B,C,Eをバグらせる
この辺は目まぐるしく入れ替わったので、よく覚えていない。
たしか、パーサーはうまく動いているけどどこかが変らしく、eliza0xがCをつまらせていたので一旦、実装の軽いBをやることに。脳内コーディングとeliza0xとのペアプロでそれなりの速度でコードがかけたがやはりどこかがおかしく、プリントアウトしてwhesonと交代した。
ライブラリの写経をしている間に、eliza0xとCの問題文をもう一度よく読み、ほしい答えを読み取る。すると、実装が降ってきたみたいなので交代。この時whesonもどこかをバグらせていたみたいなのでプリントアウトして交代。ここでだいたい2時間経過ぐらい。
怒涛のAC
完全に降りてきていたみたいなのでさっとCをeliza0xが通す。Bも関数の1つがint
を返さないと行けないのにbool
を返してたという大ポカを修正してちょこっといじれば通ったので、whesonに交代。
Eのバグは写経ミスらしかったので、コーナーケースとかの処理をして、サンプルが通ったのがだいたい終了5分前ぐらい。この間ずっと田中ヒメの過呼吸みたいなやつの真似をしていたんだけど、whesonは気づいてくれなかったし、eliza0xは落ち着いてと言っていたので、やるタイミングを完全に間違えた。
Eを無事ACし、やったぜー!となっていた時は終了2分前だった。
終了後
終了後、弊学から参加していた人々が集まった。みんな口々に感想を言ったり、ここでバグらせたなどを言ったりしていた。あとでランキング?みたいなのを見るとselectedになっていたので素直に嬉しかった。
次
次は予選本番ですね!!!!!!!!同じ調子でできれば予選突破も夢じゃなさそうなので頑張っていきたい。
今回はコーディング環境周りや、手順、役割配分などで課題も見え、単に座るだけをせずに済んだのでとても良い模擬だった。ちなみに同日のARCは参加TLEしたので、問題すら見ていない・・・・・・(参加したかった)
超・記号オンリー難読化シェル芸の材料について
時代と共にUsageも変わる・・・!
そんなお話
シェル芸botくんにmt
コマンドが入った
そういえばシェル芸botにmt入れたはずなのでマナを創り出せる。このときにLANG=Cもしちゃったんだなぁ
— ふるちゅき (@theoldmoon0602) 2018年6月13日
mt is /bin/mt https://t.co/nbaz6LLB2A
— シェル芸bot (@minyoruminyon) 2018年6月14日
LANG=C
にもしていただいたみたいなので超・記号オンリー難読化ができる
とっても嬉しい。ありがとうございます。
試してみる
喜び勇んで試しにmt
コマンドのUsageを見ようと思ったのでやってみたんですが
usage: mt [-v] [--version] [-h] [ -f device ] command [ count ] https://t.co/5gwaFj9av4
— シェル芸bot (@minyoruminyon) 2018年6月14日
思ってた出力と違います。ちなみに期待していたのは以下
$ LANG=C mt --usage Usage: mt [-?V] [-f DEVICE] [--file=DEVICE] [--rsh-command=COMMAND] [--help] [--usage] [--version] operation [count]
なんだこれーと思ったのでとりあえずmt
コマンドのバージョンを見てみると
シェル芸bot
mt-st v. 1.3
— シェル芸bot (@minyoruminyon) 2018年6月14日
default tape device: '/dev/tape' https://t.co/Vby3XvcpC4手元(Ubuntu Budgie 18.04)
$ mt --version mt (GNU cpio) 2.12 ...
え〜〜〜全然違うなるほど〜。どうやらapt
でインストールできるmt
は少し古いみたいですね
$ apt search mt-st ソート中... 完了 全文検索... 完了 mt-st/bionic 1.3-1 amd64 Linux SCSI tape driver aware magnetic tape control (aka mt)
やっぱりバージョンによってmt
のUsageが違うんですねー。時代を感じる
GNU CPIOのサイトで公開されているChangeLogを眺めてみると、何回かmt
のUsageを変更したゼみたいなことが書いてあります(英語わからん)
具体的にどのリリースからUsageが違うのか、配布されてるソースをビルドしてみたりしたんですがわからなかったです(もうちょっと調査するかも)
マナ の色が違う
しかしこのマナではスライドそのままでは 世界樹 を作ることができません。こうした色の違いを 属性 ということにしました
属性 が違うなら混ぜるか変換すればいいので 命の泉 や マナ から作れる別のコマンドを探し、世界樹 へつなげます
今回選んだのは tset
コマンドです。適当に/usr/bin
や/bin
以下から探して目についたのと、響きがなんか可愛かったので選びました。
tset
tset
は変なオプションをつけるとUsageを出力して終了します
$ tset -@ tset: invalid option -- '@' Usage: tset [options] [terminal] Options: -c set control characters -e ch erase character -I no initialization strings -i ch interrupt character -k ch kill character -m mapping map identifier to type -Q do not output control key settings -q display term only, do no changes -r display term on stderr -s output TERM set command -V print curses-version -w set window-size If neither -c/-w are given, both are assumed.
割とたくさん文字が出ますね。mt
始動をやめてtset
始動に切り替えても行けるかもしれません
ともかく、tset
とmt
の マナ で 世界樹 が作れそうです
ls --help https://t.co/cjumRIGakZ
— シェル芸bot (@minyoruminyon) 2018年6月14日
やったね
一応難読化の解説も書いておきます
# mtのUsage ___=$(mt 2>&1) # tset ____=$(${___:8:1}${___:1:1}${___:4:1}${___:8:1} -@ 2>&1) # ls --help echo ${____:10:1}${____:1:1} -${___:28:2}${____:2:1}${____:10:1}${____:15:1}
なんの解説なの?これ
LANG=C
問題
この難読化では文字を変数に格納して展開することを繰り返して難読化します。なのでマナや世界樹を作るmt
,ls --help
と言ったコマンドの出力は重要です。
今回のバージョンの違いというのもありますが、特に影響するのは言語設定です。翻訳の程度では全く難読化が成り立たなくなることもあります。
じゃあLANG=C
を必須にして難読化の先頭につければいいじゃん?という御仁もいらっしゃることかと思いますが、頑張ってアルファベットを消したのに復活させるのは悔しいのでダメです
なのでこれらの出力の中でもLANG
の値に依存しない部分を切り取ったりすることが肝要です。これは実は発案のkanataさんが 命の泉 を作るときにもやっています。僕はコレをやっていなかったので実は超・記号オンリー難読化はできてないと言えます。
現に日本語設定だとmt
のUsageは日本語訳され、以下のように出力されます
$ mt 使用法: mt [OPTION...] 操作 [回] Try 'mt --help' or 'mt --usage' for more information.
かなり違うのが解ると思います。使える文字種も減っています。
解決していく
しかし、よく見てみれば 世界樹 を得るだけであれば Try...
の行さえあれば大丈夫であることがわかります。
なのでkanataさんのやったようにいらない部分を削っていきます。
$ __=$(mt 2>&1) $ echo $__ 使用法: mt [OPTION...] 操作 [回] Try 'mt --help' or 'mt --usage' for more information. $ echo ${__##*]} Try 'mt --help' or 'mt --usage' for more information.
いい感じですね。空行が気になりますが、必要な部分だけ記号のみで取り出せそうです。
同様にls --help
の出力も必要な部分だけ取り出すようにしていきます。
$ LANG=C /bin/ls --help|grep -o .|sort -u|grep "[A-Za-z]"|xargs A B C D E F G H I K L M N O P Q R S T U W X Y Z a b c d e f g h i j k l m n o p q r s t u v w x y z $ /bin/ls --help|grep -o .|sort -u|grep "[A-Za-z]"|xargs A B C D E F G H I K L M N O P Q R S T U W X Y Z a b c d e f g h i j k l m n o p q r s t u v w x y z
ん?あれ?一緒なの?日本語にしても得られる文字種は一緒に見えます。これならLANG=Cしなくても良さそうです。少なくとも日本語環境では
しかしホンマかいなと思って発表時に得られなかった文字を探してみました。そしたらj
だけが新たに現れていました。しかも両方
なんかおかしいな〜とおもって確認したら
$ type ls ls is an alias for exa
あ〜〜〜exa
に変えてたんだった
実際j
が増えたからと言ってどうせJ
,V
が足りないのでブレース展開をするので何でも良いんじゃないかと考える方もいるかと思いますが、世界樹内での文字の位置が変わるため、割と死活問題です・・・
まとめ
今回はmt
が作るマナについて少し調査しました。その結果
- 古い
mt
と最近のmt
じゃUsageが違う(この違いを属性の違いとした) apt
で探すと出てくるのは古いほう。- 古いUsageだとそのままじゃ世界樹にならない
tset
のマナから足りない部品を集める。ただしmt
は既に使わなくてもいいレベルで文字が豊富
さらにLANG=C
が必須かもしれない問題についても少し取り組みました
- やはり環境に依存しない部分だけで難読化するのがよさそう
mt
の場合は必要な部分だけ切り取ってやればOK- つまりLANG=Cはなくても良い
- ただしツールは合わせること(
/bin/ls
を指定するとか)
難読化シェル芸。とっても楽しいですね。色んな所で話題になっているようで、これで興味を持ってもらえていたら難読化シェル芸クラスタとしてはとっても嬉しいです。ありがとうございます。
これからもヤベー難読化が見つかることを楽しみにしています。
GoでGoogle Spreadsheetにデータを書き込みたい
面倒なことは機械にやらせよう
こんな記事は死ぬほどあるけど他に書くこともない
動機
研究でめっちゃデータ取ってる。もともとデータの集計も手作業でやる系だったんだけど、この部分はシェルスクリプトとかで自動化してMarkdownの表を生成するまではやってた。しかし報告するときにMarkdownの表は見づらいみたいなことをBOSSと同期に言われたので集めてるデータをGoogle Spreadsheetで管理しようと思った。
今見たらこのMarkdownの表、自分でみてもわかりにくい
要件
書き込みたいデータ
double int int int int int int int int int
先頭が少数、その後に9つの整数が縦に続く。これを書き込みたい。
いろんなパラメータを書く欄があるのでカラムはEから始まる。行は4から。Zまで書き込んだあとはEへ戻って下の行へ移動する。
できれば次の行への移動とかも自動でやってほしい。
使う言語
最近GoをはじめたのでGoでやってみようと思った。SpreadSheetはAPIを公開してて、Go向けにもライブラリがあったのでこれでいいやみたいな
developers.google.comhttps://developers.google.com/sheets/api/quickstart/go
作ってみる
ためす
まずは試す。
この解説を一通りやってみると大体の感覚が解る。ちなみにAPIを試すだけならAPIのリファレンスの各ページからも試せる。API試せるのめっちゃありがたい
リファレンスだと自動入力が効いてるのでRequestのbodyとかの書き方をチェックするのにも使えて最高
メソッドを選ぶ
developers.google.comhttps://developers.google.com/sheets/api/reference/rest/v4/spreadsheets.values/batchUpdate
今回はspreadsheets.values.batchUpdate
を選んだUpdateをまとめてできるらしい。今の所1回につき1セットのデータしか書き込まないけど、そのうち拡張するかもしれないのでこっちにしておいた。
body
をみていると、data
っていうところがあった。data便利な単語だと思う。
それで、data
にはValueRange
型を好きな数書くといいみたい。ValueRange
型についてはリファレンスとか解説記事を見るとわかやすい
qiita.com
developers.google.comhttps://developers.google.com/sheets/api/reference/rest/v4/spreadsheets.values#ValueRange
今回最低限書き込みに必要な情報だけまとめるとこうなった
{ "valueInputOption": "USER_ENTERED", "spreadsheetId": "xxxxxxxxxxxxxxxxxxxxxxxxxx", "responses": [ { "range":"E4:E13", "majorDimension":"COLUMNS", "values":[ double, int, int, int, int, int, int, int, int, int, ], }, ], }
これをライブラリを使って投げてやればいいだけですね
実装してみる
とりあえずリファレンスのQuickStartをコピペ。かいてあるとおりにやったらAPIにアクセスできるようになった。便利な世の中やでホンマ
ここからはgoを雰囲気でかいているところが散見するのでマサカリが有ったらブンブン投げてほしいところ
変更したところはgetClient
を少し変えたぐらい
func getClient(ctx context.Context,credentialFile string) *http.Client { b, err := ioutil.ReadFile(credentialFile) if err != nil { log.Fatalf("Unable to read client secret file: %v", err) } config, err := google.ConfigFromJSON(b, "https://www.googleapis.com/auth/spreadsheets") if err != nil { log.Fatalf("Unable to parse client secret file to config: %v", err) } tokFile := "token.json" tok, err := tokenFromFile(tokFile) if err != nil { tok = getTokenFromWeb(config) saveToken(tokFile, tok) } return config.Client(ctx, tok) }
context
を受け取れるようにしただけw
次にmain
部分をかいていく
func main() { spreadsheetId := "" ctx := context.Background() client := getClient(ctx,"client_secret.json") sheetService, err := sheets.New(client) if err != nil{ log.Fatal(err) } data := []*sheets.ValueRange{ { Range: "E4:E13" Values: [][]interface{}{ 0.123, 1, 2, 3, 4, 5, 6, 7, 8, 9, }, MajorDimension: "COLUMNS", }, } reqest := &sheets.BatchUpdateValuesRequest{ ValueInputOption: "USER_ENTERED", Data: data, } res, err := sheetService.Spreadsheets.Values.BatchUpdate(spreadsheetId,reqest).Context(ctx).Do() if err != nil{ log.Fatal(err) } fmt.Printf("%#v\n",res) }
typescript
をかいてたときも思ったけど。こうやってソースの途中にJSONみたいな記述ができるってのはすごく良いと思う。どう良いかっていうのは説明できない
とりあえずこのままgo run
すれば
0.123 1 2 3 4 5 6 7 8 9
みたいなデータがかけるようになったうれしい
もっと自動化する
書き込めて嬉しいけどこれだと書き込みたいデータが変わるごとにソースを更新しないといけない。しかも手作業
ぼくは人間なので手作業をN回すれば絶対1度はミスを犯すのでここも自動にしたいわけです
とりあえずbodyをJSONから読み込めるようにします。
type Body struct { Start int `json:"Start"` End int `json:"End"` Column string `json:"Column"` Data []interface{} `json:"Data"` }
これはencoding/json
パッケージを使えば下みたいなJSONファイルと簡単にやり取りできます
{ "Start":4, "End":13, "Column":"E", "Data":[ 1,2,3,4,4,5,6,7,8,9 ] }
goはこういうところが良い感じですね。すき
リクエストを送るときは書き込みたいデータが既にまとまっているとして、終了時にはリセットしておきます。書き込みたいデータはシェルスクリプトからjq
を使って書き込むことにします
つまり
書き込みたいとき
{ "Start":4, "End":13, "Column":"E", "Data":[ 1,2,3,4,4,5,6,7,8,9 ] }
終わるとき。Data
にはjq
でデータを書き込むことにします
{ "Start":4, "End":13, "Column":"F", "Data":[] }
こうしたいので下みたいに書いてみたよ
func writeNext(b *Body) { cur := b.Column var next string st := b.Start ed := b.End if cur == "Z" { next = "E" st = ed + 2 ed = st + 9 } else { next = string([]byte(cur)[0]+1) } wd := Body{ Column: next, Data: []interface{}{}, Start: st, End: ed, } path := "next.json" jb, err := json.Marshal(wd) if err != nil{ log.Fatal(err) } ioutil.WriteFile(path,jb,0644) }
読み込み側はこうだな
func readNextJson() *Body{ path := "next.json" b, err := ioutil.ReadFile(path) if err != nil { log.Fatal(err) } var readData Body if err := json.Unmarshal(b,&readData); err != nil{ log.Fatal(err) } return &readData }
こうやって修正したmain
がこういう感じになった
func main() { spreadsheetId := "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" ctx := context.Background() client := getClient(ctx,"client_secret.json") sheetService, err := sheets.New(client) if err != nil{ log.Fatal(err) } rj := readNextJson() data := []*sheets.ValueRange{ { Range: fmt.Sprintf("%s%d:%s%d",rj.Column,rj.Start,rj.Column,rj.End), Values: [][]interface{}{ rj.Data, }, MajorDimension: "COLUMNS", }, } reqest := &sheets.BatchUpdateValuesRequest{ ValueInputOption: "USER_ENTERED", Data: data, } res, err := sheetService.Spreadsheets.Values.BatchUpdate(spreadsheetId,reqest).Context(ctx).Do() if err != nil{ log.Fatal(err) } fmt.Printf("%#v\n",res) writeNext(rj) }
あとは好きなタイミングでこれをgo run
すればいいですね。はー楽になった
終わり
Vim向けのGoプラグインが優秀なこともあって、Goはなかなか楽に書けるな〜と思いました。そのうちデータの集計とかもGoにまとめたいですね
Surface3にUbuntu Budgie 17.10をインストールする
windowsしんどいっす
ってsurface3が言ってた
surface3にUbuntu Budgie 17.10をインストールする
2年ほど前に中古でsurface3を買いました。価格は5万円ぐらいだったと思います。
買った時にはすでに尿液晶で、白いUIだと尿まみれでした
最近、強いノートPCを支給され、winマシンは要らなくなったのでsurfaceをUbuntuマシンにしようと思っていろいろ迷走したのでその備忘録です
先に行っておくと、なんでうごいてるのかわからないという内容の記事ですので注意です。
SurfaceLinux
超有益な情報が集まっているredditがありました。名前も超そのままだ・・・
ざっくりやったこと
- Ubuntu 17.10を普通にインストール。しばらく使っていたらWi-Fiが死んだので終了
- Ubuntu MATE 17.10をインストール。こんどはSurfaceLinuxのGUIDEに沿ってやってみるも不安定なWi-Fi
- Ubuntu Budgie 17.10をインストール。後述のppaで追加できるカスタムカーネルを試そうとしたら16.04までだった。GUIDEを試して再起動すると画面がつかなくなった
- LiveUSBつくるのがダルかったのでUbuntu Budgie 17.10をもう一度インストール。GUIDEはすっ飛ばした。なぜか安定しているのでここで終わり
採用したやつ
OSはUbuntu Budgie 17.10を使いました。
Plank
やTilix
がデフォでインストールされているとか、何もしなくても黒UIなところとかシンプルで綺麗とかもあるんですが、コイツでしかちゃんと動いてないっていうのもあります。
これの前にUbuntu
,Ubuntu MATE
を試したんですがダメでした。僕はどちらも17.10をインストールしたんですが、redditにある解決策やGUIDEを試してもうまく動きませんでした。
Budgie 17.10だとインストールした瞬間から安定して動作していました。というわけでそれについてです
LiveUSBを作る
Ubuntu Budgie 17.10のLiveUSBを作ります。作り方は解説記事がたくさんあるのでそちらに任せます。
インストールする
LiveUSBからUbuntu Budgieを起動するにはSecureBootをOFFにする必要があります。
BIOSを出すときは、WindowsでShiftキーを押しながら再起動ボタンを押せば楽にいけて便利です
Ubuntu Budgieが起動したらインストールします。今回はWindowsとお別れするのでディスクを削除してインストールしました。
Ubuntuのアップデートを同時にインストールしましたし、MP3とかも一緒にやりました
インストールしたあと
IBus
なんかIBusが死んでいます。このへんのツールにこだわりはないので動きそうなFcitxに乗り換えます。
Ubuntu Budgieじゃないとき
やはり普通のPCではないのでいろいろ普通に問題が山積みです。例えばWi-Fiが突然死したり、画面がすごい勢いで明滅します。
16.04をインストールする場合は上のリンク先が非常に役に立ちます。ppaを追加してインストールできるkernalが超いい感じらしいです(試せてない)
サスペンドできない
これは解決策がGUIDEに書いてあります。試してないので試したら追記します
バッテリー情報が取得できない
できないです。SurfaceLinux内でも話題に上がっていることの一つでした。どうやらカーネルのバグらしく・・・
106231 – Call-By-Reference-Constant - battery and power adapter not working, MSHW0011 driver needed, even in windows - Surface 3
パッチはできてるみたいで、PRもmergeされたぜ!みたいなこと書いててカーネル4.13に入るかもな!やったー!カスタムカーネル無しで動くわね!って感じだったけど結局revertされたらしい。
ここで配布されているパッチ当てればなおるのかな?英語もパソコンもなんもわからん