それマグで!

知識はカップより、マグでゆっくり頂きます。 takuya_1stのブログ

習慣に早くから配慮した者は、 おそらく人生の実りも大きい。

mac で ⌘コマンドやオプション⌥を入力する方法。

Macのキーボードに印字された記号を入力する

コマンド⌘やオプション⌥など、Macのキーボードにはには記号がいっぱいある。

これを入力する方法を紹介します。

方法1:変換する

変換するのが手っ取り早い

入力したいときは、変換するのが手っ取り早いです。

オプション

f:id:takuya_1st:20191216162146p:plain

コマンド

f:id:takuya_1st:20191216162208p:plain

変換にない場合は、登録しましょう(後述

方法2文字ビューワーから

文字ビューワーを使って入力すると速いです。

f:id:takuya_1st:20191216162338p:plain

文字ビューワーの呼び出し方。

右上の日本語の「あ」と出てくるところをクリックして、絵文字ビューワーを表示します。 f:id:takuya_1st:20191216162537p:plain

そのままでは、キーボードの記号が出て来ません。

なので、リストをカスタマイズして一覧に表示します。

f:id:takuya_1st:20191216161729p:plain

f:id:takuya_1st:20191216162513p:plain

技術的記号を選択して、一覧に追加すると、⌘やオプションなどの記号が使えるようになります。 f:id:takuya_1st:20191216161700p:plain

日本語入力に辞書で登録する。

Google IME など日本語入力ソフトに、変換候補の文字列として辞書登録しておくと良いと思います。 f:id:takuya_1st:20191216163826p:plain

辞書登録の例。

f:id:takuya_1st:20191216164854p:plain

JSでHTTP GET クエリ文字列を JS オブジェクトから作成する-

js で http query をオブジェクトからビルドする

JavascriptのオブジェクトをURLのGET引数に変換したいときには、npm 探しますか? ライブラリ探しますか?

URLSearchParams ができています。

GETパラメタを扱うときは、これがあれば、だいたい解決する

https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams

URLSearchParams は 古くは querystring と呼ばれた関数です。パワーアップして帰ってきました。

https://developer.mozilla.org/en-US/docs/Archive/Add-ons/Add-on_SDK/High-Level_APIs/querystring

Object( hash ) → queryString の変換

手軽で便利な使い方です。

new URLSearchParams( {a:1 , b:3} ).toString();
'a=1&b=3'

便利ですね。

ネストには注意

そのままでは、ネストできません。ネストできません。

オブジェクトのネスト:

Object文字列になります。

> new URLSearchParams( {a:{x:10,y:11}, b:3} ).toString();
'a=%5Bobject+Object%5D&b=3'

残念。toString されているだけです。

配列でネスト

配列も同じです。

> a = new URLSearchParams( {a:[10,11], b:3} ).toString();
'a=10%2C11&b=3'
> decodeURIComponent(a)
'a=10,11&b=3'
>

残念ですね。toStringされているだけです。

URLのGETパラメタを正しく扱うので、同名のパラメタが2個あっても良い。

これもオブジェクトを扱うときの注意点なのですが、キー名はダブることがあります。

オブジェクトではダブリを扱えないのですが、URLSearchParamsは扱えてしまいます。

> new URLSearchParams("start=大阪&via=心斎橋&via=難波&dest=天王寺")
URLSearchParams { 'start' => '大阪', 'via' => '心斎橋', 'via' => '難波', 'dest' => '天王寺' }

Objectをパラメタ変換しようとしたり逆にObjectで取り出そうとしたとき、ネストをどう扱うか、ダブるキー名をパラメタに含めるなど、キーを扱うときは注意を払う必要があります。

Object {} と URLSearchParams は等価交換できないのです。配列になってくれたりしないのです。

iteratorで使うURLSearchParams

> new URLSearchParams("start=大阪&via=心斎橋&via=難波&dest=天王寺").entries()
URLSearchParams Iterator {
  [ 'start', '大阪' ],
  [ 'via', '心斎橋' ],
  [ 'via', '難波' ],
  [ 'dest', '天王寺' ] }

こちらは、全パラメータをきれいにiterator で回るのです。

Iterator からさらオブジェクトへ(2021-11-19追記)

Iterator のママでは少々使いにくいので Object.fromEntries を使って便利に使う。

var cond = Object.fromEntries(new URLSearchParams(window.location.search))
cond['start']

Object.fromEntries はバージョンを選ぶので、polyfill したほうが無難。

node の組込querystringなら、配列になってくれる

https://nodejs.org/api/querystring.html
querystring.parse("start=大阪&via=心斎橋&via=難波&dest=天王寺")
[Object: null prototype] {
  start: '大阪',
  via: [ '心斎橋', '難波' ],
  dest: '天王寺'
}

node 組み込みの querystring ならば、配列になってくれていたので、このほうが便利だったと思うんですね。

きれいなオブジェクトになる querystring

URLSearchParams と違って node の querystring ならオブジェクトになってきれいだと思う。

> a = querystring.parse("start=大阪&via=心斎橋&via=難波&dest=天王寺")
[Object: null prototype] {
  start: '大阪',
  via: [ '心斎橋', '難波' ],
  dest: '天王寺'
}
> a
[Object: null prototype] {
  start: '大阪',
  via: [ '心斎橋', '難波' ],
  dest: '天王寺'
}
> querystring.stringify(a)
'start=%E5%A4%A7%E9%98%AA&via=%E5%BF%83%E6%96%8E%E6%A9%8B&via=%E9%9B%A3%E6%B3%A2&dest=%E5%A4%A9%E7%8E%8B%E5%AF%BA'
> decodeURI(querystring.stringify(a))
'start=大阪&via=心斎橋&via=難波&dest=天王寺'

結論

URLSearchParamsが使えますが、ネストなど複雑なパラメタは扱いづらい。

node 環境下では querystring を使える。

ならば、ブラウザにnpmで互換パッケージをポーティングしたほうが便利なのかもしれません。

参考資料

Hello Worldを 2進数の0/1 にバイナリに変換してランダムパッド(使い捨て暗号

バイナリ変換してXORして遊びたい

暗号技術入門を呼んでいると、XORがバンバン出てくるので、ちょっとやってみようと思い立った

暗号技術入門 第3版

暗号技術入門 第3版

ruby で計算するのが早い

>> "Hello".each_byte.map{|e| e }.join(" | " )
=> "72 | 101 | 108 | 108 | 111"
>> "Hello".each_byte.map{|e|  sprintf("%b", e)  }.join(" | " )
=> "1001000 | 1100101 | 1101100 | 1101100 | 1101111"

これをXORと併せて計算しましょう

本当は、C言語のプログラミングの授業でやりたいんだけどねぇ。

Ruby で ランダムパッドをして遊ぶ。

>> "Hello".each_char.zip( "World".each_char )
=> [["H", "W"], ["e", "o"], ["l", "r"], ["l", "l"], ["o", "d"]]
>> "Hello".each_byte.zip( "World".each_byte ).map{|e| e[0] ^ e[1] }
=> [31, 10, 30, 0, 11]
>> "Hello".each_byte.zip( "World".each_byte ).map{|e| e[0] ^ e[1] }
=> [31, 10, 30, 0, 11]
>> "Hello".each_byte.zip( "World".each_byte ).map{|e| e[0] ^ e[1] }.zip("World".each_byte).map{|e| e[0] ^ e[1] }.map(&:chr).join
=> "Hello"
>>

Hello を World で XORで符号化する

>> "Hello".each_byte.zip( "World".each_byte ).map{|e| e[0] ^ e[1] }.map{|e|  sprintf("%08b", e)  }.join(" | " )
=> "00011111 | 00001010 | 00011110 | 00000000 | 00001011"

この結果を、World以外の文字列でXORするともとに戻らない。

>> "Hello".each_byte.zip( "World".each_byte ).map{|e| e[0] ^ e[1] }.zip("abcdef".each_byte).map{|e| e[0] ^ e[1] }.map(&:chr).join
=> "~h}dn"

ただし、ただし、一部が一致すると。。。

>> "Hello".each_byte.zip( "World".each_byte ).map{|e| e[0] ^ e[1] }.zip("world".each_byte).map{|e| e[0] ^ e[1] }.map(&:chr).join
=> "hello"
>>

このように、一部が一致するとXORのランダムパッドでは暗号とは言えなくなる。

出てきた文字が正しいかわからない

>> "Hello".each_byte.zip( "World".each_byte ).map{|e| e[0] ^ e[1] }.zip("XYZaa".each_byte).map{|e| e[0] ^ e[1] }.map(&:chr).join
=> "GSDaj"

ここでは、暗号化に使う鍵に、「World」という文字列を採用しましたが、ランダムの使い捨てパッドである必要があります。

こうやって扱ってみると、ランダムパッドによる使い捨て暗号は、色々と問題があることがわかる。

安いLG Ultra HD モニタ(4k対応) はMacのRetinaモードに非対応(部分対応)だった件

4k ディスプレイのすべてがRetinaモードに対応してるわけではない。

4kディスプレイを幾つか試していて気づいたんですが、LGのディスプレイの一部モデルは、Retina解像度で縦横の長さを任意に変更できない模様。

LG Ultra HD のもの

Macのディスプレイ設定で見ると次のように見える。Full HDではRetinaモードになるのですが、フルHD以外の拡大率150% などは一切考慮されてないようで。。。

何故だろうか。とても不思議だった。

f:id:takuya_1st:20191129152032p:plain

Acer のモニタの場合

Acerのモニタで試したら、Retinaの任意の倍率に変更できる。28インチと32インチで試したら次のように表示される。

f:id:takuya_1st:20191129152046p:plain

IO-DATA のモニタの場合

IO−DATAのモニタの場合でも、Retinaの倍率選択が出てきて、好きな倍率の設定できて嬉しい。

f:id:takuya_1st:20191129152125p:plain

LGはガチャ

LGでも任意に設定できるものがあるのですが、安いものは駄目みたい。買ってみて接続しないとわからないので、実質的にガチャ回す感じ。

Amazonプライムで購入したら返品ができるのですが、それでも返品ガチャを回すひと手間はめんどくさい。やっぱりK国製より、台湾メーカーですね。

LGでも問題はないんだろうけど、今後ちょっと追調査が必要だと思われる。

おすすめの4kモニタ

この辺がMacで接続するにはおすすめだと思う。価格的にも3万円くらいで済むし、Amazonブラックフライデーサイバーマンデーセールで8%オフとか

 

Acerno27インチはスピーカーの性能と、HDMI検出がエラーになることが多いなど問題点は多いが、価格と性能は問題ないし、妥協しないと駄目だった。

USB-C電源と一体化したケーブルが便利

USB-Cと一体化したモニタが魅力だけど、USB-Cで一体化したモニタは高いので、こういうのを使うと使い勝手を享受しながら、価格を妥協できる

macOSでwinRAR の rar ファイルを「作成」する

macOS でも winRAR のファイルアーカイブを作成したい。

zip / tar.gz でいいだろと思われるんだろうけど、リカバリレコードを付与できるアーカイブ形式ってやっぱりrar しかないよね。

brew の formula 作った

winrar からコマンドバイナリを取得してインストールして管理するのは面倒なので、 brew 用のformula を作っておいた

https://github.com/takuya/homebrew-winrar-osx

brew tap takuya/homebrew-winrar-osx

インストール

brew install takuya/homebrew-winrar-osx

基本的な使い方はLinux版などと同じ。

rar コマンドでのファイルの作り方。

rar a 作りたいアーカイブ名 ファイル1 ファイル2 ...

リカバリレコードを付与したファイルの作成

リカバリレコードを5%付与した場合。

rar a -rr5p  out.rar dir/files*

ファイルをまるっと付与してRARファイルを作成することができる

rar ファイル

rar は加齢臭がするんだろうけど、他に手軽なツールってあまりないですよねぇ。zip ファイルはあれこれ制限があるし tar.gz こそ加齢臭がする。

展開(解凍)するなら

rar よりも lsar / unar のコマンドが便利。

https://takuya-1st.hatenablog.jp/entry/2016/08/03/145534

関連記事

Linux でwinrar のrarファイルを圧縮展開・rr3% つける。rarで文字コードも嬉しい? - それマグで!

tcpdump でパケットのサイズが指定以上より大きいものを取り出す。

tcpdumpで パケット長でフィルタを掛けたい

小さいパケットは無視したり、一定以上のサイズのものだけを取り出したい。

tcpdump -i eth0 greater 500

greater の条件を使うことで、パケットの長さを元にフィルタをかけることができる。逆は less

組み合わせる

tcpdump は組み合わせで使うことが多いので、条件をいれフィルタを掛けてあげる。

tcpdump -i eth0 dst 102.168.2.206 and udp and geater 1000

and で繋げばパケットをフィルタできる。 -i デバイス はそれとは別に tcpdump で取得するネットワーク・デバイス(インタフェース)を指定している。

tcpdump で UDP のパケットを表示する

tcpdump を使って UDP を指定する

tcp は syn ack があってパケットがたくさん出てきますが、 UDP はそうでもない。

tcpdump -i eth0 udp

UDPIPアドレスを指定する

tcpdump のコマンドは、フィルタ単体というより、いくつかのフィルタを組み合わせて使うのが便利。

tcpdump -i eth0  dst 192.168.2.206 and udp

and をつかって dst /src のIPなどと組み合わせてやれば、リアルタイムにパケットをきれいに見ることができる。

Number と parseInt()の挙動の違い / 数字に変換するとひと言でいうが奥深い

parseInt と Number の挙動の違い。

parseInt と Number という2つがある。文字列 → 数値の型変換の関数を使おうとしてみんな一度くらいこの違いが気になるんじゃない?

違いをパパッと確認しよう

parseInt と Number の差異が如実に顕出するのは、次の例ではないでしょうか。

// 文字列が含まれる
parseInt("64GB")   //  64
Number("64GB")  // NaN
// 少数
parseInt("0.1")  //  0
Number("0.1")   // 0.1

IntがほしいならparseInt が便利。

parseInt の結果を見てほしい

parseInt("1")      //  1
parseInt("10")     //  10
parseInt("0.1")    //  0
parseInt("010101") //  10101
parseInt("64GB")   //  64
parseInt("¥64")   // NaN
parseInt("64円")   // 64
parseInt("第64回") // NaN
parseInt("2e1")    // 2
parseInt("0xFF") // 255
parseInt("0xFF times")// 255

少数が処理できないという、parseInt の名前の通りの仕様を除けば、概ね楽ちんに変換できる。

事前に文字列を処理して、必要なフォーマットに変換する手間がない。

parseInt は関数の名前( parseInt =Int に解釈する )の通りの動作だったり。

Number は本当の意味で型変換

Number は JS の Number 型であり、Number型の変数を返すので、本当の意味で型変換だと思うの

Number("1")    // 1
Number("10")   // 10
Number("0.1")   // 0.1
Number("010101") // 10101
Number("64GB")  // NaN
Number("¥64")  // NaN
Number("64円")  // NaN
Number("第64回") // NaN
Number("2e1")  // 20
Number("0xFF") // 255
Number("0xFF times") // NaN

個人的な結論

parseIntは、単位が含まれたりする入力値してぱぱっと数字へ変換したいとき → 10px とか 100円とか、CSSの値を数値にしたいときに便利

Numberは厳密に文字列事前処理し、その結果を数字に正確に変換するときに使う。

基本はNumberを使う、事前処理などを無精するときはparseIntもまだまだ許容されると思う。

少数にならないCSSの文字列 element.style.width とか処理をするなら重宝する。

tcpdump コマンドで ping の応答 ( icmp echo reply ) だけに絞り込む

tcpdumpping の 応答パケットだけを取り出す。

tcpdumpLinuxルーターのなかで実行しているときに、デバッグしてるときにパケットを見ます。

ネットワーク間の forward が正しく動いているか、iptables の設定が正しいかどうか、NATできてるかどうか。など。

ちょっとした調査でping を打ち込んで調べることが多いと思います。そういうときに、icmp だけ取り出しても表示が多すぎて面倒くさい。

reply だけを表示する

tcpdump  icmp[icmptype] = icmp-echoreply'

指定のホストから reply が戻ってきたか調べる

IP を指定と組み合わせて使うと便利

tcpdump  src 192.168.1.1 and icmp[icmptype] = icmp-echoreply'

指定のホストに echo リクエストが転送されか調べる

逆も同じ

tcpdump  'dst 192.168.100.1 and icmp[icmptype] = icmp-echo'

組み合わせで便利。

バイスを指定したり、IPを指定で便利になる。単純に icmp を見るよりいいと思う。echo / echo-reply を表示するターミナルを開けておいて、設定を反映させる。

設定を変えたあと、画面にログが表示され始めたら、ネットワーク設定が正しく行えたことがわかる。

ログが流れないなら、設定ミスってるってわかるので視覚的にわかりやすくていい。中身見なくていいのが強い。

設定ミスしがちな「戻りパケット」の経路設定の切り分けをするときに、明確に分かれるから面白い

参考資料

https://hackertarget.com/tcpdump-examples/

ssh のポート転送をipv6 / ip6 宛にする

ssh のポートフォワーディングのやり方IPv6アドレス編

ssh のポート転送は便利で手軽に使えるものです。

ipv6 でも同じです。

ssh -L 8080:[2001:a253:838xxxxxx]:80  root@192.168.100.1

sshでもIPv6の指定はcurlなど同じ

[v6 addr]:port のように、ブラケットで囲めばいい。

[2011:123:ff:]:port

関連資料

takuya-1st.hatenablog.jp

tcpdump で icmp (ping)のパケットを表示する

icmp で ping の受信を見たい

tcpdump を使って届いてるパケットを見ることが出来る。 ping の応答が返ってこないしとしても、応答パケットのルーティング設定が間違っている可能性もある。

そのため、ping の宛先でパケットがちゃんと届いているかチェックするとルーティングテーブルの問題を切り分けやすい。

tcpdump icmp

これで、ping パケットを見ることが出来る。

icmp を送信元で絞る

ping パケットが指定したホストから送信されているかどうかを見るには、tcpdump のフィルタリング機能で、フィルタすると便利。

tcpdump src 192.168.1.123 and icmp

and 条件で送信元を絞ることが出来る。

知っておくとネットワークトラブルでパニクらずに住む

関連資料

tcpdump でパケットをのぞき見る方法まとめ。10分で僕にも出来た。tcpdumpの使い方 - それマグで!

initramfs の本体 init.rd を展開して、busybox をみたり、起動設定を見直してみる。

init.rd を展開してみる

init.rd は initramfs を起動するためもの。/boot のパーティションに存在している。

update-initramfs で起動する。grub から起動される最小限のlinux

展開してみる・・・?

initrd ファイルはcpio なので 、cpio で展開しようとしてみる。

あれれ

cd `mktemp -d` && sudo cat /boot/initrd.img-`uname -r` | cpio -ivd
.
kernel
kernel/x86
kernel/x86/microcode
kernel/x86/microcode/AuthenticAMD.bin
62 ブロック

1ファイルしかない?そんな馬鹿な

takuya@d001:/tmp/tmp.On03d1x9GP$ tree . 
.
└── kernel
    └── x86
        └── microcode
            └── AuthenticAMD.bin

3 directories, 1 file

調べてみたら、このcpio ファイルはいくつかの組み合わせなのでうまく行かない。

linux - Why is it that my initrd only has one directory, namely, 'kernel'? - Unix & Linux Stack Exchange

そうだね。cpio ってtar みたいなもんだもんな

binwalk コマンドをいれて、中身を見てみると。。。末尾にgzip 圧縮されたものがある。

takuya@d001:/tmp/tmp.On03d1x9GP$ binwalk /boot/initrd.img-`uname -r` 

DECIMAL       HEXADECIMAL     DESCRIPTION
--------------------------------------------------------------------------------
0             0x0             ASCII cpio archive (SVR4 with no CRC), file name: ".", file name length: "0x00000002", file size: "0x00000000"
112           0x70            ASCII cpio archive (SVR4 with no CRC), file name: "kernel", file name length: "0x00000007", file size: "0x00000000"
232           0xE8            ASCII cpio archive (SVR4 with no CRC), file name: "kernel/x86", file name length: "0x0000000B", file size: "0x00000000"
356           0x164           ASCII cpio archive (SVR4 with no CRC), file name: "kernel/x86/microcode", file name length: "0x00000015", file size: "0x00000000"
488           0x1E8           ASCII cpio archive (SVR4 with no CRC), file name: "kernel/x86/microcode/AuthenticAMD.bin", file name length: "0x00000026", file size: "0x00007752"
31184         0x79D0          ASCII cpio archive (SVR4 with no CRC), file name: "TRAILER!!!", file name length: "0x0000000B", file size: "0x00000000"
31744         0x7C00          ASCII cpio archive (SVR4 with no CRC), file name: "kernel", file name length: "0x00000007", file size: "0x00000000"
31864         0x7C78          ASCII cpio archive (SVR4 with no CRC), file name: "kernel/x86", file name length: "0x0000000B", file size: "0x00000000"
31988         0x7CF4          ASCII cpio archive (SVR4 with no CRC), file name: "kernel/x86/microcode", file name length: "0x00000015", file size: "0x00000000"
32120         0x7D78          ASCII cpio archive (SVR4 with no CRC), file name: "kernel/x86/microcode/.enuineIntel.align.0123456789abc", file name length: "0x00000036", file size: "0x00000000"
32284         0x7E1C          ASCII cpio archive (SVR4 with no CRC), file name: "kernel/x86/microcode/GenuineIntel.bin", file name length: "0x00000026", file size: "0x0024CC00"
2443952       0x254AB0        ASCII cpio archive (SVR4 with no CRC), file name: "TRAILER!!!", file name length: "0x0000000B", file size: "0x00000000"
2444288       0x254C00        gzip compressed data, from Unix, last modified: 2019-10-18 08:19:18

ここから、bs がわかるので、それを取り出してみる。

takuya@d001:/tmp/tmp.On03d1x9GP$ dd if=/boot/initrd.img-`uname -r`  bs=2444288 skip=1 | gunzip | cpio -tdv | head
drwxr-xr-x  13 root     root            0 Oct 18 17:19 .
drwxr-xr-x   2 root     root            0 Oct 18 17:19 bin
-rwxr-xr-x   1 root     root         9424 Feb  1  2019 bin/cpio
-rwxr-xr-x   1 root     root         5751 Feb 14  2019 bin/cryptroot-unlock
-rwxr-xr-x   1 root     root       108760 Jan 14  2019 bin/date
-rwxr-xr-x   1 root     root         9624 Feb  1  2019 bin/dd
-rwxr-xr-x   1 root     root         8792 Feb  1  2019 bin/dmesg
-rwxr-xr-x   1 root     root         9992 Feb  1  2019 bin/fstype
-rwxr-xr-x   1 root     root         8920 Feb  1  2019 bin/halt
-rwxr-xr-x   1 root     root        19872 Feb  1  2019 bin/ipconfig

お、ファイルが見えるぞ。

それではこのファイルを取り出してみる

takuya@d001:/tmp/tmp.IrvVwlLK99$ dd if=/boot/initrd.img-`uname -r`  bs=2444288 skip=1 of=img.cpio.gz
takuya@d001:/tmp/tmp.IrvVwlLK99$ gunzip img.cpio.gz 
takuya@d001:/tmp/tmp.IrvVwlLK99$ cpio -idv < img.cpio 
takuya@d001:/tmp/tmp.IrvVwlLK99$ ll 
合計 194292
drwx------ 13 takuya takuya      4096 10月 18 17:35 ./
drwxrwxrwt 21 root   root        4096 10月 18 17:35 ../
drwxr-xr-x  2 takuya takuya      4096 10月 18 17:35 bin/
drwxr-xr-x  3 takuya takuya      4096 10月 18 17:35 conf/
drwxr-xr-x  2 takuya takuya      4096 10月 18 17:35 cryptroot/
drwxr-xr-x 11 takuya takuya      4096 10月 18 17:35 etc/
-rw-rw-r--  1 takuya takuya 198891008 10月 18 17:34 img.cpio
-rwxr-xr-x  1 takuya takuya      7077 10月 18 17:35 init*
drwxr-xr-x 10 takuya takuya      4096 10月 18 17:35 lib/
drwxr-xr-x  2 takuya takuya      4096 10月 18 17:35 lib64/
drwxr-xr-x  2 takuya takuya      4096 10月 18 17:35 run/
drwxr-xr-x  2 takuya takuya      4096 10月 18 17:35 sbin/
drwxr-xr-x 10 takuya takuya      4096 10月 18 17:35 scripts/
drwxr-xr-x  7 takuya takuya      4096 10月 18 17:35 usr/
drwxr-xr-x  4 takuya takuya      4096 10月 18 17:35 var/

取り出せました。

chroot してみる

takuya@d001:/tmp/tmp.IrvVwlLK99$ sudo chroot . /bin/sh


BusyBox v1.27.2 (Ubuntu 1:1.27.2-2ubuntu7) built-in shell (ash)
Enter 'help' for a list of built-in commands.

# 

更に単純な方法

takuya@d001:/tmp/tmp.gTlrfnehcs$ unmkinitramfs /boot/initrd.img-`uname -r`  . 

systemd.path で path(パス) を監視する。

systemd でパス監視機能を使う

systemd.path を試していきます。

パスの監視というと理解しくいかもしれませんが、フォルダの監視です。フォルダを監視してなんかやります。もちろんファイルも監視できます。

inotify でアプリを書くより手軽です。

はじめに

systemd でパスを監視することができる。

xxxx.path と xxxx.service をペアで作成し登録すればオッケ。

制限事項

再帰的(recursive)なパス監視はできない。

inotify を使っているので、 nfsなどネットワーク越しでは使えない。

gvfs/gio でマウントしていると inotifyが発動するはずなので cifs でもつかそう

ユーザー空間にファイルを作って作って試す

今回は、次のファイルを作って試していきます。

~/.config/systemd/user/desktop.service
~/.config/systemd/user/desktop.path

systemd のユーザー空間について、過去の資料を参考に

~/.config/systemd/user/desktop.service

[Unit]
Description=DesktopSample

[Service]
WorkingDirectory=/home/takuya/Desktop
ExecStart=/bin/echo Hello From Service 

[Install]
WantedBy=default.target

~/.config/systemd/user/desktop.path

[Unit]
Description=DesktopSample

[Path]
## PathModified と PathChanged は別物
## 再帰的( recursively ) にパスの監視はできない。
## inotify をベースにしている
PathChanged=/home/takuya/Desktop
#PathModified=/home/takuya/Desktop
[Install]
WantedBy=default.target

ロードする

systemctl --user daemon-reload

起動する

enable して

systemctl --user enable desktop.service
systemctl --user enable desktop.path

restart しておく

systemctl --user restart desktop.service
systemctl --user restart desktop.path

コレで起動するので、あとはログを見ながら、動作する様子を見る

journalctl でログを開いておく

path の監視が起動したときのログ

journalctl --user -f  -u desktop.path

service が起動したときのログ

journalctl --user -f  -u desktop.service

-f をつけているので、ログは tailf と同じく following される。

動作を実験してみる。

いくつか、ファイルを作成したり、ファイルを更新したりして パスを書き換える実験をしておく

cd ~/Desktop/
echo 更新テスト > a 
echo 更新テスト2 > a 
echo 更新テスト3 > a  
echo 更新テスト4 >> a  
echo 更新テスト5 >> a  
rm a 
touch a 
chmod 777 a 
rm a 
mkdir  a 
rmdir a 

あとは、ログを見ながら、このタイミングでイベント発火するとか確認しておけばいい。

再帰的監視はできない

ディレクトリを再帰的に監視する機能は使えないようです。

代わりに、PathChanged を複数書くことができます。

このように複数書くことができます。

[Path]
PathChanged=/home/takuya/Desktop
PathChanged=/home/takuya/Desktop/.hidden
PathChanged=/home/takuya/Desktop/.gitignore
PathChanged=/home/takuya/Desktop/.git

更新について

PathModifiedとPathChanged がある。man systemd.path を見るとあれこれ書いてある。

PathChanged について

PathChanged= may be used to watch a file or directory and activate the configured unit whenever it changes. It is not activated on every write to the watched file but it is activated if the file which was open for writing gets closed.

PathModified については

PathModified= is similar, but additionally it is activated also on simple writes to the watched file.

たぶん、次のようなことだと思う。 - PathChanged は open → close されたら発動 - PathModified append された発動

open されたまま、追記されていくデータファイルやログファイルを追いかけるでもない限り PathChanged で問題ないと思われる。

その他の監視モード

  • パスが存在したらなにかする。
  • パスに変更がアレばなにかする。
  • ディレクトリが空っぽ以外になったらなにかする。
  • ファイルを指定をglob でやる

などがある。それぞれ次の名前で定義されている

PathExists=, PathExistsGlob=, PathChanged=, PathModified=, DirectoryNotEmpty=

簡単に実装できて便利。

「できる」だけであり、痒いところまで手が届くような使い勝手がいいものではない。

ただ、systemd のユーザー空間と組み合わせて、ユーザー空間で独自にぱぱっと関する程度ならお手軽でいいと思う。

細かい部分まで実装したいなどの用途に向かない。

例えば、ファイルが新規作成された、更新された、truncate されたとか、ディレクトリ内部に作成されたファイル名が知りたい。などなど。 細かい点について作業をしたいもののが欲しいなら inotify 系の python や npm/fsevent 系を使って細々書いておき、書いたpython を service 化するほうがずっといいだろうな。

systemd.path はgnome デスクトップなどで作成されるファイルを手軽に監視して同期したいなどで重宝すると思います。

参考資料

  • man systemd.path

関連資料

https://takuya-1st.hatenablog.jp/entry/2019/08/09/004829

ubuntu を4kディスプレイで拡大率125%や150%などの任意解像度をwindowsやMacみたいに選ぶ

4K モニタを使っていると、しんどい。

ubuntu で 4k ディスプレイを使っていると、解像度が細かすぎてしんどい。

windows 10 からは拡大率150% などが選べるが、 ubuntu はデフォルト設定では 200%/100%しか選べなかった。

125%と150% を有効にする。

gsettings で 実験的機能を有効にしてあげると、解像度の拡大倍率を指定できて、MacOSretina モードみたいなことができるようになる。

gsettings set org.gnome.mutter experimental-features "['scale-monitor-framebuffer']"
gsettings set org.gnome.mutter experimental-features "['x11-randr-fractional-scaling']"

設定するとこの通り、150%が出現する。これで快適になる。

f:id:takuya_1st:20191021180026p:plain
解像度

もとに戻すとき

もとに戻すには reset を使う

gsettings reset org.gnome.mutter experimental-features

参考資料

https://www.linuxuprising.com/2019/04/how-to-enable-hidpi-fractional-scaling.html?m=1

NetworkManagerがunmanaged(管理なし)になった問題を解決した

network-manager で管理できない。

network-manager で unmanaged になって、ubuntu desktop (gnome) からネットワークが管理できなかった。

依存関係が多くて、問題がわかりにくい。

ubuntu は 1年前から、 netplan が導入されているので、ubuntu server は systemd-networkd で管理、 ubuntu desktop は NetworkManager で管理することになっている。

それでは、/etc/network/interfaces はどうなったのか?

network-manager のときは、 network-manager が /etc/network/inteface をparsing して管理デバイスを見つけた上で除外し、残ったデバイスを管理するようになっている。

ただし、この設定はキャッシュされるらしい。(マジだったら、コレはホントめんどくさいわ)

networkd のときは、 networkd の起動後に /etc/network/intefaces を取得して管理する。こっちも面倒くさい。

デスクトップubuntu では networkd はいらない

使ってもいいんだけど、依存関係が多くて面倒くさいので、除外して切り分ける

sudo systemctl stop systemd-networkd.service
sudo systemctl disable systemd-networkd.service
sudo systemctl mask systemd-networkd.service

netplan の設定をシンプルにする。

netplan は networkmanager を使う設定にして、シンプルにする。

takuya@:~$ cat /etc/netplan/01-netcfg.yaml 
network:
  version: 2
  renderer: NetworkManager

netplanの設定を再生成してあげる

sudo netplan generate

これで、余計なものは動かなくなる。

ただし、場合分けのために除外し過ぎくらい除外してる。なので、netplan apply すら動かない。

この辺は、正直言ってubuntu の問題だろうなぁ。 networkmanager を指定してるのに 一旦 networkd を経由しようとしている。

takuya@:~$ sudo netplan generate 
takuya@:~$ sudo netplan apply 
Failed to start systemd-networkd.service: Unit systemd-networkd.service is masked.
Traceback (most recent call last):
  File "/usr/sbin/netplan", line 23, in <module>
    netplan.main()
  File "/usr/share/netplan/netplan/cli/core.py", line 50, in main
    self.run_command()
  File "/usr/share/netplan/netplan/cli/utils.py", line 130, in run_command
    self.func()
  File "/usr/share/netplan/netplan/cli/commands/apply.py", line 44, in run
    self.run_command()
  File "/usr/share/netplan/netplan/cli/utils.py", line 130, in run_command
    self.func()
  File "/usr/share/netplan/netplan/cli/commands/apply.py", line 153, in command_apply
    utils.systemctl_networkd('start', sync=sync, extra_services=netplan_wpa)
  File "/usr/share/netplan/netplan/cli/utils.py", line 82, in systemctl_networkd
    subprocess.check_call(command)
  File "/usr/lib/python3.7/subprocess.py", line 363, in check_call
    raise CalledProcessError(retcode, cmd)
subprocess.CalledProcessError: Command '['systemctl', 'start', '--no-block', 'systemd-networkd.service']' returned non-zero exit status 1.

NetworkManager の設定は多ファイルに分割されている

NetworkManager の設定ファイルは、/etc/NetworkManager だけでなく、 /usr/lib/NetworkManager などにデフォルト設定あったりして、それらがマージされて /etc/NetworkManager で上書きするようになっている。

takuya@:~$ sudo NetworkManager  --print-config
# NetworkManager configuration:
 /etc/NetworkManager/NetworkManager.conf (lib: 10-dns-resolved.conf, no-mac-addr-change.conf)
(run: netplan.conf) 
(etc: 10-globally-managed-devices.conf, default-wifi-powersave-on.conf)


## 略

/etc/NetworkManager で設定ファイルを見てもすべてが記載されているわけでじゃないので、 --print-config で最終的な設定を確認するのがポイント

ifupdown を使わないようにする。

ifupdown は /etc/network/interfaceを管理するので、 ifupdown も切り分けのために一旦無効化する。

sudo apt uninstall ifupdown
sudo apt uninstall ifupdown2
sudo apt uninstall netscript-2.4 

NetworkManager.conf でunamanged デバイスをすべて上書きして無効化する。

設定方法は、いくつか考えられるのだけど、umamanged になる問題を解決するために、すべての設定をOFFにしたり消していく。

takuya@:~$ cat /etc/NetworkManager/NetworkManager.conf 
[main]
#plugins=ifupdown,keyfile
plugins=keyfile
dns=default

[keyfile]
unmanaged-devices=
#[ifupdown]
#managed=true

[device]
wifi.scan-rand-mac-address=yes

ちなみに、ifupdownのmanaged は ifup/ifdown で管理される /etc/network/intefacesを nmcli で管理するかどうか。

restart する

あれこれ、余計なものを排除した結果動くようになる、

takuya@:~$ sudo systemctl status network-manager.service 
● NetworkManager.service - Network Manager
   Loaded: loaded (/lib/systemd/system/NetworkManager.service; enabled; vendor preset: enabled)
   Active: active (running) since Mon 2019-10-21 17:20:33 JST; 10s ago
     Docs: man:NetworkManager(8)
 Main PID: 4474 (NetworkManager)
    Tasks: 4 (limit: 4915)
   Memory: 4.0M
   CGroup: /system.slice/NetworkManager.service
           └─4474 /usr/sbin/NetworkManager --no-daemon

10月 21 17:20:33 j5005 NetworkManager[4474]: <info>  [1571646033.9682] device (enp3s0): state change: ip-config -> ip-check (reason 'none', sys-iface-state: 'assume')
10月 21 17:20:33 j5005 NetworkManager[4474]: <info>  [1571646033.9809] device (enp3s0): state change: ip-check -> secondaries (reason 'none', sys-iface-state: 'assume')
10月 21 17:20:33 j5005 NetworkManager[4474]: <info>  [1571646033.9813] device (enp3s0): state change: secondaries -> activated (reason 'none', sys-iface-state: 'assume')
10月 21 17:20:33 j5005 NetworkManager[4474]: <info>  [1571646033.9819] manager: NetworkManager state is now CONNECTED_LOCAL
10月 21 17:20:33 j5005 NetworkManager[4474]: <info>  [1571646033.9832] manager: NetworkManager state is now CONNECTED_SITE
10月 21 17:20:33 j5005 NetworkManager[4474]: <info>  [1571646033.9834] policy: set '有線接続 1' (enp3s0) as default for IPv4 routing and DNS
10月 21 17:20:33 j5005 NetworkManager[4474]: <info>  [1571646033.9876] device (enp3s0): Activation: successful, device activated.
10月 21 17:20:33 j5005 NetworkManager[4474]: <info>  [1571646033.9885] manager: NetworkManager state is now CONNECTED_GLOBAL
10月 21 17:20:33 j5005 NetworkManager[4474]: <info>  [1571646033.9892] manager: startup complete
10月 21 17:20:34 j5005 NetworkManager[4474]: <info>  [1571646034.0348] bluez5: NAP: added interface 00:09:DD:50:6C:BF

管理下に置かれる

takuya@:~$ nmcli d
DEVICE  TYPE      STATE     CONNECTION 
enp3s0  ethernet  接続済み  有線接続 1 
lo      loopback  管理無し  --         

unmanaged だったのが

f:id:takuya_1st:20191021172309p:plain

managed になる。

f:id:takuya_1st:20191021172202p:plain

なんでこんなにめんどくさいのか

過渡期とはいえ、systemd 関連の更新と整合性を保つために、あれこれ機能が追加されている。

あれこれ過渡期だからでしょうね。 nmcli や netplan を諦めて /etc/network/interfacesだけに戻すか、素直にnetworkd だけにしたほうが将来的に楽なのかなぁ。

今回驚いたのは ifup/down のコマンドを提供するパッケージが3つもあったことだった。ネットワーク周りはカオスですね。