それマグで!

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

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

exim4 のスマートリレーはローカルホストに向かない?

Exim4 を設定してて気づいたんだけど、

Exim4のスマートリレーは、「外部アドレス」が前提になっていて、ローカルホストへは向かないようだ。

詳細設定をいじくり回さないといけなさそう

exim4 のスマートリレーは 127.0.0.1:12345 のように、同一ホストへは転送できない。

これは、exim4 のローカルホストへの配送とバッティングするのだろうか、どうやってもローカルホストの別ポートへExim4がフォワードすることはなかった。

Exim4から、XOAUTH2のDockerにフォワードしたかったんだけど。。

もう、postfix 入れることにした。

サービスアカウントでGmailアクセスできない?

XOAUTH2も、アプリパスワードもめんどくさいので、サービスアカウントをアカウントを作ってGmailのアクセスを試みた。

あれこれ、ためしたけど、無理っぽいなぁ。普通にWEBアプリとして自分のアプリで自分をOAuthするしかなさそう。

他にもいろいろな人が試みたり、調べたりしているが、Google のサービス・アカウントの機能で、GmailAPIアクセスはできない。Gmail.sendだけでもさせてくれればいいのに・・・

Service accounts cannot access @gmail.com mailboxes. You must use one of the other supported OAuth 2.0 authorization scenarios described at https://developers.google.com/identity/protocols/OAuth2.

https://stackoverflow.com/questions/39510514/gmail-api-service-account

The short answer is no, it's not possible to perform service-account impersonate of a @gmail.com account. The key reason is that although the service account OAuth flow doesn't involve an authorization screen, at the end of the day someone must still say "I authorize this application to impersonate this user."

Now for a while there was a trick where you could take an @gmail.com user through the regular 3-legged flow, and once they approved it use the service account flow from then on. This lead to some strange problems however, so we've disabled that option. This may be why there was disagreement in the past about if this is possible.

https://stackoverflow.com/questions/39510138/google-oauth2-impersonate-service-account-with-usergmail-com/39534420#39534420

参考資料

rsyslog の転送機能でログを集約する

ログ集約

rsyslog/syslog で設定する

受信側

sudo -E cp /etc/rsyslog.conf{,.bak}
sudo systemctl restart rsyslog
sudo -E vim /etc/rsyslog.conf

18行目付近を、有効にする。TCP 514 ( または UDP 514 )

--- /etc/rsyslog.conf.bak       2022-08-29 08:13:05.132978351 +0900
+++ /etc/rsyslog.conf   2022-08-29 08:13:16.340874261 +0900
@@ -18,8 +18,8 @@
 #input(type="imudp" port="514")

 # provides TCP syslog reception
-#module(load="imtcp")
-#input(type="imtcp" port="514")
+module(load="imtcp")
+input(type="imtcp" port="514")

送信側

conf.d が使えるのを確認

$ sudo -E cat /etc/rsyslog.conf | grep rsyslog.d
# Include all config files in /etc/rsyslog.d/
$IncludeConfig /etc/rsyslog.d/*.conf

ファイルを作る

sudo -E touch /etc/rsyslog.d/remote.conf   
sudo -E vim /etc/rsyslog.d/remote.conf

転送先を記入( TCP@@ip_or_host:514, UDPなら@ip_or_host:514)

*.* @@raspi-ubuntu.lan:514     

再起動して反映

sudo systemctl restart rsyslog

実験する

ログを書き出すコマンドが次の通り

logger -p syslog.info -t TEST "Test"

ログをtail して確認

受信側

takuya@raspi-ubuntu:~$ sudo tail -f  /var/log/syslog

送信側

takuya@pi-zero:~ $ sudo tail -f  /var/log/syslog

送信側でログを書き出す。

logger -p syslog.info -t TEST "Hello from pi-zero"

結果

きちんと集約しているのがわかる。

無事に、ログが転送されことがわかる。

転送済ログの分割

受信側では、ログをサーバーごと、エラーレベルごとに振り分けすることが出来る。(参考資料 https://www.secuavail.com/kb/tech-blog/tb-210521-01-2/)

書込みレート

デフォルトでは、5秒、200行まで書き込みを行いますが、200行以降は破棄されてしまいます。 5秒に200行以上ログが転送されるようなシステムの場合、チューニングが必要な項目になります。 https://qiita.com/tasakii/items/10db42392c487d5276da

ログの転送量には上限が決められているので注意する。

journald のとの関係?

journalctl はsyslog に転送する。

$ cat /etc/systemd/journald.conf  | grep -i syslog
#ForwardToSyslog=yes
#MaxLevelSyslog=debug

journalctl と syslog が互いにログを保持しているのでわかにくい。

以前は、syslog に転送しjournald自身は破棄していたため、journaldはvolatile (揮発性)になっていたようだが、いまは、journald もauto(デフォルト動作不明:たぶんファイル保存)で自分でログを保持するので、結果としてsyslog と journaldの両方にログが出来ることになる。

たとえば、次のように複雑に入れ込んで人も、やっぱり両方に出ている。

https://boscono.hatenablog.com/entry/2015/12/30/095620 /dev/kmsg -> imklog -> rsyslog -> /var/log/messages -> journald -> imjournal -> rsyslog -> /var/log/messages という流れになっているっぽいので

参考資料

https://www.kagoya.jp/howto/engineer/itsystem/syslog/ https://www.secuavail.com/kb/tech-blog/tb-210521-01-2/ https://isleofhoso.com/journald-conf/

あとで

journald と syslogd

https://gihyo.jp/admin/serial/01/ubuntu-recipe/0546

エクスプローラでプロパティを開くキーボードショートカット

ファイルのプロパティを開く

矢印でファイルを選択し
Alt-Enter

サクッと開く、TABで移動

開いた項目は「Tab」「Shift-Tab」で移動する

マウスは時間がもったいない。無駄動作が多すぎる

フォルダを右クリック、プロパティまでダウン、クリック。長いわ。カーソルを合わせるのがもうしんどい。

ノートPCの人はおすすめ

ノートPCにマウスを接続しないとまともに使えない人は、ショートカットがおすすめです。

写真アプリでも使えます、

写真(microsoft photos)アプリでも同じような操作ができるようになっている。

参考資料

https://support.microsoft.com/ja-jp/windows/windows-%E3%81%AE%E3%82%AD%E3%83%BC%E3%83%9C%E3%83%BC%E3%83%89-%E3%82%B7%E3%83%A7%E3%83%BC%E3%83%88%E3%82%AB%E3%83%83%E3%83%88-dcc61a57-8ff0-cffe-9796-cb9706c75eec

エクスプローラーのファイル一覧にフォーカスする

Ctr-Tab をすると、サクッとフォーカスするので便利

Win-E  エクスプローラーを開く
Ctrl- Tab ファイル一覧へフォーカス
Ctrl- Shift-Tab 、で左のツリーへフォーカス

エクスプローラーのキーボードショートカットがないと、矢印キーで選択が不便。

画像ファイルから全部のexifを除去する

方法1:exiftool

exiftool -all:all= -r /path/to/file [/path/to/file...]

方法2:mogrify

mogrify -strip /path/to/file

結果

サイズが変わってる。mogrify は画質いじってるのでは・・・

$exiftool -all:all= -r sample1.heic
$mogrify -strip sample2.heic
$exiftool -all  sample1.heic > a
$ exiftool -all  sample2.heic > b
$ ls -l sample*.heic
-rwxrwxrwx 1 takuya takuya 3751758 Aug 25 17:46 sample1.heic
-rwxrwxrwx 1 takuya takuya 2327024 Aug 25 17:46 sample2.heic

exiftool と mogrigfy の差分をみると

きれいに消えてるのがmogrify 、一部残ってるのがexiftool 。

vimdiff a b

どっちを使うのか迷うところであるが、画像をアップロードしたり公開するならmogrify ですかね。

写真のExiftをJSONで取り出す。

ファイルのExiftをJSONで取り出したい。

EXIFJSONで取り出せたら、集計が便利なんじゃないのかと思って調べたら、対応していた。

exiftool -s -G -j ファイル名...

実行サンプル

exiftool -s -G -j 2021-04-04_15-56-43_926.heic  | jq .

出力サンプル

[
  {
    "SourceFile": "2021-04-04_15-56-43_926.heic",
    "ExifTool:ExifToolVersion": 12.42,
    "File:FileName": "2021-04-04_15-56-43_926.heic",

    "EXIF:BrightnessValue": 5.483765591,
    "EXIF:ExposureCompensation": 0,
    "EXIF:MeteringMode": "Multi-segment",
    "EXIF:Flash": "Off, Did not fire",
    "EXIF:FocalLength": "4.2 mm",
    "EXIF:GPSSpeed": 0,
    #略
    "Composite:LensID": "iPhone XR back camera 4.25mm f/1.8"
  }
]

複数ファイル対応です。

exiftool -s -G -j ファイルA ファイルB

複数ファイルを前提としたフォーマットになっています。

出力は次のようになってました。

[
   { Exif 情報 },
   { Exif 情報 },
   { Exif 情報 },
   { Exif 情報 },
]

参考資料

https://stackoverflow.com/questions/2089194/example-of-how-to-parse-exiftool-json-output-in-haskell

windows terminal だけでUAC出来るようになっていた。

Windows Terminal だけでUAC出来るようになっていた。

Windows Terminal に設定が登場していた

いつのまに。。。

UACPowershellの呼び出し。

UACPowershellを起動するのは、Win-X then A でメニューから呼び出していたが、ターミナルから使うほうが便利かもしれない。

ウインドウをすべて閉じるをキーボードから高速で呼び出す

このClose All (すべて閉じる)をキーボード・ショートカットで呼び出す方法は無いのかな。

方法1:タスクバーにフォーカスする

Win - T でタスクバーにフォーカス
矢印キーで選択
Appキーでメニュー呼び出し

Appキー(右クリックメニュー)のキーが、存在しないノートPCのキーボードなどもあるので万能じゃないが、確実。

縦配置で、Win-Tを押したときにフォーカスが動く例。

方法2:ジャンプリストのショートカットを使う

Win-Alt- 数字{1,2,34,5,6,7,8,9} でジャンプリストのショートカットが使える。

左から順に1,2,3,4、5となっている

Win-Alt- 1
Win-Alt- 2
Win-Alt- 3

Appキーを使う方法より、確実だが、5以降は一瞥識別が厳しいので難しいわ。

Windows難しい

写真(photo)とエクスプローラーで便利

写真のプレビューや、エクスプローラーをたくさん開いたときに、ものすごく便利です。

そして、Excelファイルを大量に開いて作業しているときにも重宝します。

参考資料

windowsで最速サインアウト

Windows最速サインアウトにはいろいろある

ショートカットキー の連携

Win+X でメニューを呼び出して、メニューのアクセスキーをたどる

Win - X  → u → i

ロックより確実

ロックだと、ユーザー名が残る。

ADで共同でログインして使い分ける端末だと、ロックが大変。

シャットダウン・メニューを使う

シャットダウン・メールを使う場合

Win -D でデスクトップ表示してから、Alt-F4でシャットダウンメニューをだして、上矢印を2回

Win -D 
Alt-F4
↑
↑

これでもいいけど、Alt-F4が押しづらいので好きじゃない。

参考資料

https://support.lenovo.com/jp/ja/solutions/HT505153

jc と jq の組み合わせで、ファイル名のクォートが便利

jc と jq の組み合わせで、ファイル名のクォートが便利

ファイル名にスペースが入る

次のように、ファイル名にスペースが入って、コマンドで処理するときにIFS(区切り)として解釈されちゃってとっても邪魔。

takuya@:$ls  -l  *5576*
-rwxrwxrwx 1 takuya takuya 2733101 Oct 26  2021 'IMG_5576 (2).JPG'
-rwxrwxrwx 1 takuya takuya     689 Oct 26  2021 'IMG_5576 (3).AAE'
-rwxrwxrwx 1 takuya takuya     689 Oct 26  2021  IMG_5576.AAE
-rwxrwxrwx 1 takuya takuya 2964682 Oct 26  2021  IMG_5576.JPG
-rwxrwxrwx 1 takuya takuya 2439727 Oct 26  2021 'IMG_E5576 (2).JPG'
-rwxrwxrwx 1 takuya takuya 2679346 Oct 26  2021  IMG_E5576.JPG

jc コマンドと jq コマンドでサクッと

これで、確実にクォートがされる。

takuya@:$ ls  -l  *5576*  | jc --ls | jq .[].filename
"IMG_5576 (2).JPG"
"IMG_5576 (3).AAE"
"IMG_5576.AAE"
"IMG_5576.JPG"
"IMG_E5576 (2).JPG"
"IMG_E5576.JPG"

jc コマンドで、JSONにできると、処理が格段に楽ですね。

bashでぶん回すときに、楽ですね。インストールは面倒だけど。

エスケープ処理がめんどくさくて、python/ruby のexec()スクリプト作ることも多いが、jc | jqで少し楽ができそう

関連資料

jc コマンドの例 - コマンドの結果をJSONの配列やオブジェクトにする。 - それマグで!

prinft でクォートする例 - シェルでファイル名をエスケープにしてクォート地獄を解決する。 - それマグで!

montage(画像を並べる)するときにファイル名を入れたい。

montage するときにファイル名を入れたい

画像をならべて、インデックスの画像を生成したい。

インデックスプリントのような、証明写真のような、写真をならべてサクッとインデックス・プリントにしたい。

似た写真があるときに並べて表示することで「違い(差分)」を、目視し、目で差異を確認したいとき、montageコマンドが便利。でもファイル名がわからないと差分がわかってもどこのファイルかが分かりづらい。そこでファイル名を入れたい。

ファイル名をラベルとして表示する例

montage \
    -geometry 1200x \
    -pointsize 150 -font Liberation-Serif-Italic \
    -set label '%f\n%wx%h' \
        "IMG_5576 (2).JPG" 
        "IMG_5576.JPG" 
        "IMG_E5576 (2).JPG" 
        "IMG_E5576.JPG" 
    out.jpg

montage コマンド

montage a.jpg b.jpg c.jpg d.jpg out.jpg

montage コマンドで出力幅指定 (縦幅を省略して自動計算

montage -geometry 1200x 

montage コマンドでファイル名を入れる

montage -set label '%f\n%wx%h'
  • %f ファイル名
  • \n 改行
  • %w
  • %h

montage コマンドにフォントとフォントサイズを指定

montage -pointsize 150 -font Liberation-Serif-Italic 

フォントはフォント一覧から選ぶ。

フォント一覧の取得

montage -list font

出来上がりサンプル

参考資料

lxc のコンテナ内部でパーミッションエラーでapt updateができなくなった。

lxc 内で パーミッションエラー

lxc のapt を最新版にしようとしたらエラーになった。

lxc exec myhost apt update 
chown to _apt:root of directory /var/lib/apt/lists/partial failed - SetupAPTPartialDirectory (1: Operation not permitted)
W: chown to _apt:root of directory /var/lib/apt/lists/auxfiles failed - SetupAPTPartialDirectory (1: Operation not permitted)

/var/lib/apt/lists の中がおかしい

nobody になってる。。。

lxc exec myhost  ls -l /var/lib/apt/lists/partial/ -ld
drwx------ 1 nobody nogroup 0 Aug 18 19:05 /var/lib/apt/lists/partial/

ただしくはこうなるはず

ssh root@sample ls  /var/lib/apt/lists/partial/ -ld
drwx------ 2 _apt root 6  8月 18 11:48 /var/lib/apt/lists/partial/

lxc のストレージをマウントして修正を試みる

lxc storage list
+-----------+--------+----------------------------------------------+-------------+---------+---------+
|   NAME    | DRIVER |                    SOURCE                    | DESCRIPTION | USED BY |  STATE  |
+-----------+--------+----------------------------------------------+-------------+---------+---------+
| bt01      | btrfs  | /var/snap/lxd/common/lxd/disks/bt01.img      |             | 4       | CREATED |
+-----------+--------+----------------------------------------------+-------------+---------+---------+
| default   | zfs    | /var/snap/lxd/common/lxd/disks/default.img   |             | 2       | CREATED |
+-----------+--------+----------------------------------------------+-------------+---------+---------+

ストレージを利用しているコンテナを確認し、念のため一時的に停止しておく

$ lxc storage info bt01
info:
  description: ""
  driver: btrfs
  name: bt01
  space used: 19.04GiB
  total space: 49.94GiB
used by:
  instances:
  - jitsi
  - nextcloud
  - rails
  - rclone-web
$ lxc stop  jitsi nextcloud rails rclone-web

ストレージをマウントして様子を見る

$ losetup  | grep bt01
/dev/loop7          0      0         1  0 /var/snap/lxd/common/lxd/disks/bt01.img           1     512
$ losetup  | grep bt01 | awk '{print $1}'
/dev/loop7          
$ sudo mount $(losetup  | grep bt01 | awk '{print $1}')  /mnt 
$ ls /mnt
$ sudo ls /mnt/containers/nextcloud/rootfs
$ sudo ls /mnt/containers/nextcloud/rootfs/var/lib/apt

様子を見ると、

$ sudo ls /mnt/containers/nextcloud/rootfs/var/lib/apt
$ sudo ls /mnt/containers/nextcloud/rootfs/var/lib/apt/lists -l
total 145820
drwxr-xr-x 1 root root 0 Aug 18 19:05 auxfiles
-rw-r--r-- 1 1000000 1000000   115942 Jul  9 19:14 debian-mirror.s
-rw-r--r-- 1 1000000 1000000 45506443 Jul  9 18:12 debian-mirror.s
-rw-r--r-- 1 1000000 1000000 52296931 Jul  9 18:14 debian-mirror.s
-rw-r--r-- 1 1000000 1000000 17446169 Jul  9 18:13 debian-mirror.s
-rw-r--r-- 1 1000000 1000000 30235019 Jul  9 18:12 debian-mirror.s
-rw-r--r-- 1 1000000 1000000    44066 Aug 18 17:20 debian-mirror.s
-rw-r--r-- 1 1000000 1000000     9833 Jun 12 04:58 debian-mirror.s
drwx------ 2 _apt root 6  8月 18 11:48 /mnt/containers/nextcloud/rootfs/var/lib/apt/lists/partial/

なんかおかしいので、 全部消して、作り直した。

sudo rm -rf /mnt/containers/nextcloud/rootfs/var/lib/apt/lists 
sudo mkdir /mnt/containers/nextcloud/rootfs/var/lib/apt/lists 
sudo chown 1000000 :1000000  /mnt/containers/nextcloud/rootfs/var/lib/apt/lists 

パーミッションエラーは出なくなった。

なぜ、パーミッションがおかしくなったのかは謎だけど。バックアップとか書き戻しでミスしてたかもしれない。

まとめ

lxc のストレージは直接サワれるっていうことをメモとして残しておく。

パーミッションエラーでもなんとかなるんだなというのが学び。

コマンドの結果をJSONの配列やオブジェクトにする。- jc コマンド

コマンドの結果をいい感じに、配列にしたい

コマンドの実行結果をJSONにしたいと思った。

https://dev.classmethod.jp/articles/jc-tool/

jc コマンド

jc コマンドは、STDINを読み取って JSONに変換してくれる。

数多くのパーサーが用意されてプリインいる、パーサーがなくてもjc はそこそこ便利。

jc コマンドを試す。

$ id | jc --id --pretty

結果はJSONになる。

{
  "uid": {
    "id": 1000,
    "name": "takuya"
  },
  "gid": {
    "id": 1000,
    "name": "takuya"
  },
  "groups": [
    {
      "id": 1000,
      "name": "takuya"
    },
    {
      "id": 4,
      "name": "adm"
    }
  ]
}

プリインストールのパーサーがいっぱいある

(略
    --ls                `ls` command parser
    --ls-s              `ls` command streaming parser
    --lsblk             `lsblk` command parser
    --lsmod             `lsmod` command parser
    --lsof              `lsof` command parser
    --lsusb             `lsusb` command parser
    --nmcli             `nmcli` command parser
    --passwd            `/etc/passwd` file parser
    --ping              `ping` and `ping6` command parser
    --systemctl         `systemctl` command parser
    --systemctl-lj      `systemctl list-jobs` command parser
    --systemctl-ls      `systemctl list-sockets` command parser
    --systemctl-luf     `systemctl list-unit-files` command parser
    --systeminfo        `systeminfo` command parser
    --top               `top -b` command parser
(略

プリインなパーサがなくても大丈夫。いい感じにJSON配列になる。

サクッと行ごとに出力して

$ apt list vim* 2>/dev/null | grep vim | cut -d '/' -f 1  | sort | head -n 5
vim
vim-addon-manager
vim-addon-mw-utils
vim-airline
vim-airline-themes

jc / jq でサクッと整形する。

apt list vim* 2>/dev/null | grep vim | cut -d '/' -f 1  | sort | head -n 5 | \
    jc --kv | \
    jq keys

行ー>配列になる。

[
  "vim",
  "vim-addon-manager",
  "vim-addon-mw-utils",
  "vim-airline",
  "vim-airline-themes"
]

Key/Valueを使ってオブジェクトにする

プリインストールがないなら、脳死で考えるのをやめて キーバリューに仕立てる

Key/Valuegrep / sed /awk で作る

cat /etc/php/8.0/cli/php.ini | grep -v \; | grep = | grep session | sed 's/ = /:/'
session.save_handler:files
session.use_strict_mode:0
session.use_cookies:1
session.use_only_cookies:1
session.name:PHPSESSID
session.auto_start:0
session.cookie_lifetime:0
session.cookie_path:/
session.cookie_domain =
session.cookie_httponly =
session.cookie_samesite =
session.serialize_handler:php
session.gc_probability:0
session.gc_divisor:1000
session.gc_maxlifetime:1440
session.referer_check =
session.cache_limiter:nocache
session.cache_expire:180
session.use_trans_sid:0
session.sid_length:26
session.trans_sid_tags:"a=href,area=href,frame=src,form="
session.sid_bits_per_character:5

jc にかける

cat /etc/php/8.0/cli/php.ini | grep -v \; | grep = | grep session | sed 's/ = /:/' | jc --kv --pretty
{
  "session.save_handler": "files",
  "session.use_strict_mode": "0",
  "session.use_cookies": "1",
  "session.use_only_cookies": "1",
  "session.name": "PHPSESSID",
  "session.auto_start": "0",
  "session.cookie_lifetime": "0",
  "session.cookie_path": "/",
  "session.cookie_domain": "",
  "session.cookie_httponly": "",
  "session.cookie_samesite": "",
  "session.serialize_handler": "php",
  "session.gc_probability": "0",
  "session.gc_divisor": "1000",
  "session.gc_maxlifetime": "1440",
  "session.referer_check": "",
  "session.cache_limiter": "nocache",
  "session.cache_expire": "180",
  "session.use_trans_sid": "0",
  "session.sid_length": "26",
  "session.trans_sid_tags": "a=href,area=href,frame=src,form=",
  "session.sid_bits_per_character": "5"
}

jc コマンドでシェルの実行結果を JSONに変えられる

jc コマンドは対応コマンドはきれいにJSONに代わる。非対応のものは、--kv で Key/Value として処理すれば簡単に jq で解釈できる。

インストール

pip3 install jc

パーサーが無いコマンド

パーサーがない場合は、jc --csv jc --kvJSONにすればいいので、awk コマンドでいい感じに整形すればいい。

整形結果をフィルタするときは、 ` jc --kv | jq .で jq と組み合わせできるのでよい。