それマグで!

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

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

Raspian(raspberryPi)でらじる★らじるを聞く

らじる★らじる を raspi で聴ければ

Raspberry Pi にスピーカー繋いで、ラジオを流せればとっても楽ちんだと思いません?

omxplayer だけでいけます。

2017-09から、らじる★らじるが m3u8 に変更になっているので HLS のm3u8 を指定するだけなのでとても簡単

omxplayer --timeout 60s -o local https://nhkradiobkr1-i.akamaihd.net/hls/live/512291/1-r1/1-r1-01.m3u8

たったこれだけ。

timeout がデフォルトの10s だとakamai の仕様で接続が切れるらしいので、 --timeout で長めに設定する必要がある。

-o は アウトプットを オーディオジャックに指定している。raspi は alsa とか設定するより omxplayer を使うのが一番ラクですよね。

心配なら --audio_queue を付けても良いかもしれない

omxplayer が rtmpe と ヘッダ追加 に対応してくれたらradikoもrtmpdump 無しでいけるのになぁ。

Debian のバージョンと名前を確認する。

バージョン番号

takuya@raspberrypi:~ $ cat /etc/debian_version
8.0

バージョン名などの各種情報

takuya@raspberrypi:~ $ cat /etc/os-release
PRETTY_NAME="Raspbian GNU/Linux 8 (jessie)"
NAME="Raspbian GNU/Linux"
VERSION_ID="8"
VERSION="8 (jessie)"
ID=raspbian
ID_LIKE=debian
HOME_URL="http://www.raspbian.org/"
SUPPORT_URL="http://www.raspbian.org/RaspbianForums"
BUG_REPORT_URL="http://www.raspbian.org/RaspbianBugs"
takuya@raspberrypi:~ $

ぱぱっと見て使えるファイル名は

  • /etc/os-release
  • /etc/debian_version

これで、バージョン番号と名前が確認できます。

他にもいろいろありますが。この方法が手軽だと思う。

今回は raspberry pi の raspbian で確認しました。

2018/12/03

記述を追加

Raspian(raspberry Pi)のアップグレード(jessie→stretch)

raspi の stretch があるので、アップグレードします。

方法は、通常の debian アップグレードと同じでいいですね。

事前準備

できるだけ最新版にしておく。

sudo apt-get update &&  sudo apt-get upgrade -y

jessie の記述を探す。

grep jessie /etc/apt/ -R 

名前を置換する

Debianのアップグレードと同じように、/etc/apt でバージョン名を指定する

sudo sed -i 's/jessie/stretch/g' /etc/apt/sources.list
sudo sed -i 's/jessie/stretch/g' /etc/apt/sources.list.d/raspi.list 

自動更新してたので念の為にコレも。

sudo sed -i 's/jessie/stretch/g' /etc/apt/apt.conf.d/50unattended-upgrades

名前が置換されたのを確認

takuya@raspberrypi:~ $ sudo grep jessie /etc/apt/  -R
takuya@raspberrypi:~ $

コレだけが置換された。

takuya@raspberrypi:~ $ sudo grep stretch /etc/apt/  -R
/etc/apt/apt.conf.d/50unattended-upgrades://   n,codename      (eg, "stretch", "stretch-updates")
/etc/apt/apt.conf.d/50unattended-upgrades://   ${distro_codename}      Installed codename (eg, "stretch")
/etc/apt/apt.conf.d/50unattended-upgrades://      "o=Raspbian,n=stretch";
/etc/apt/sources.list:deb http://mirrordirector.raspbian.org/raspbian/ stretch main contrib non-free rpi
/etc/apt/sources.list:#deb-src http://archive.raspbian.org/raspbian/ stretch main contrib non-free rpi
/etc/apt/sources.list.d/raspi.list:deb http://archive.raspberrypi.org/debian/ stretch main ui
/etc/apt/sources.list.d/raspi.list:#deb-src http://archive.raspberrypi.org/debian/ stretch main ui

更新する。

sudo apt update

更新が終われば、アップグレードしたいけど・・・

もし心配なら、シミュレーターでシミュレーションする。

apt --simulate upgrade 
apt --simulate dist-upgrade 

パッケージを余りたくさん入れてなかったり、httpdサーバーの設定を変えてなかったり、smb.conf とかサーバの設定を変えてなければ、ほとんどなにも起きないのでシミュレーターは必要ないと思う。

アップグレード

sudo apt dist-upgrade

アップグレードが終了

takuya@raspberrypi:~ $ cat /etc/debian_version
9.0

子孫プロセスも含めて殺す。Kill children and ancestors

プロセスの子孫を消したいなーって

絶対、車輪の再発明になるので検索させていただきました。

再帰で殺す

kill コマンドとppid をきっちり使いこなせば、ちゃんと理解できるんだろうけど、それを説明するのはかったるいので、再帰呼出しがイメージしやすいのではなかろうか。

killtree.sh
#!/usr/bin/env bash


killtree() {
    local parent=$1 child
    for child in $(ps -o ppid= -o pid= | awk "\$1==$parent {print \$2}"); do
        killtree $child
    done
    kill $parent
}


killtree $@

参考資料

https://stackoverflow.com/questions/392022/best-way-to-kill-all-child-processes

Chromeがキーチェインを使う条件

chrome が keychain のダイアログを聞いてきた!?

chrome ってキーチェイン使わないとおもってたら、キーチェインのダイアログを聞いてきたのであたらためて調べてみた

chrome が キーチェインを使う条件

Chromeはキーチェインを「読み込み専用」で使うようです。

chrome のパスワードの使い方(読込

  • Chromeの内蔵パスワードを調べる
  • なかったら、キーチェインを調べる。

の OR 条件になっているようです。

Chromeのパスワードの利用法(書込み

書込みは、内蔵パスワード保存のみのようです。 更新もないようです。

chrome でパスワードの使い方

いったん、Safari起動して保存してからChromeで開くと良いようですね。

でも昨日は

あきらかに、ChromeがKeychainsに新規項目追加したと思うんだけど。なんで新規項目追加されたのかちょっとつい調査したい。

chrome のDNSキャッシュを消す方法

dns 書き換えてると chromeDNSキャッシュが邪魔

PC/MacDNSキャッシュを消しても、なんかダメだなと思ったら、どうやらChromeDNSキャッシュがあるようで。

DNS触ってnginx を切り替えてるときに、chromedns cache はうざい。

chromeDNSキャッシュの確認と削除

chromeDNSキャッシュは chrome-urls からアクセスできる。 → chrome://net-internals/#dns

chrome://net-internals/#dns

f:id:takuya_1st:20170908002307p:plain

DNS はちゃんとキャッシュ見ましょう。

ほんとうはDNSのキャッシュ設定を変えれば良いんだろうけど。キャッシュ消すのが一番早い

DNS浸透待ちはしないでね。浸透言うな警察が来るよ。cacheにも注意しよう

2021-01-14

cache で検索しても出てこないのでキーワードを見直し

python の shlex でコマンドに渡す字句を分割する

コマンドを Popen に渡すときに

コマンドを組み立てた文字列を配列で渡すなら、split が便利だけど、shlex.split ならさらに安全に渡せるらしい。

    self.prcs = Popen( shlex.split(cmd), shell=False )

たしかに文字列をsplit すると暴走するものね。

また shlex.quote もあるのでこちらも便利そう

Shell経由させないほうが孫プロセスを作らなくて楽なイメージ有る。

関連資料

takuya-1st.hatenablog.jp

参考資料

https://docs.python.org/3.6/library/shlex.html

MariaDB のユーザー認証をPAM経由にする。

mariaDB にしました。

mariaDB に変えたので、PAMによる認証連携は、最初から付属してます。便利!

mariadb でPAM Authをするには

mysql の管理者(root) で ログインしてプラグインを有効化する

INSTALL SONAME 'auth_pam';

これでほとんど完了。あー楽。

PAM経由するユーザーを追加する

mysql にユーザーを追加する。

CREATE USER takuya identified via pam

これでいい。楽ちん。

MySQLがPAMを参照できるよにする。

ここは何もしなくて良さそう。auth を使うみたい。以前に mysql + pam であれこれ設定してるので、パーミッションとかは省略して動いた。

もし、mysqlmariadb といった名前でPAMに書きたい場合(たとえば www-data や apachepostgresql などと共通名にしたいとか)

ユーザーできたので、プラグインがPAMに認証を丸投げできるように、PAM側で受け取れるように設定する。

CREATE USER takuya identified via pam USING 'my-pam-name' # 

MySQLの場合

以前はこっちをやってた。

http://takuya-1st.hatenablog.jp/entry/2015/03/16/164719

brew で upgradable/アップグレード可能なパッケージを一覧する

apt には apt list –upgradable がある

同じことを homebrew の brew コマンドでやるにはどうすればいいか

outdated を使う

brew outdated

これで、新しくなってる brew のパッケージの一覧が取得できる。

参考資料

https://stackoverflow.com/questions/12946505/how-can-i-tell-which-homebrew-formulae-are-upgradable

pkexec のインストール

pkexec がみつならないの。。

探したら、policykit-1 というパッケージに含まれてた。

http://manpages.ubuntu.com/manpages/xenial/man1/pkexec.1.html

pkexec の pk は policy kit の略なんですね

ubuntu の LTS Serverには含まれてなかったんですよね。。。便利だから使ってるけど余り一般的ではないコマンドなのなか。本来なら pkexec の代わりには何を使うべきなんだろう。

sudo だと環境変数の設定を sudoers に書く必要とかあるし、gksudo だと面倒だし一覧楽な do as だと思うんだけどな。

コマンドからunix ドメインソケットのパーミッションを実験する

unix:/var/.../unicorn.sock にアクセスできないの

nginx の プロキシの upstream を unix ドメインソケットに設定したのだけれど動かないのね。 だから、ソケットが正しく動いてるかテストしてみたかったの。

nc コマンドと組合せて使うことで、テストできる。

nc -U unix:/path/to/some.sock

コレを使えばコマンドからunixソケットにアクセスして、アクセス可能かテストできるし、パーミッションもここでテストできる。

echo ' GET / '  | nc  -U /path/to/unicorn.sock

これで応答するか調べられる。

パーミッションのテストをするときは pkexec を使えば楽

pkexec でnc 実行して別ユーザからの読込とアクセスを見てみたら確認できた

echo "GET /" | sudo  pkexec --user www-data nc -U   /var/opt/gitlab/gitlab-workhorse/socket
nc: unix connect failed: Permission denied

これで、 www-data ( nginx ) から gitlab のソケットにアクセスできてないことが分かる。

usermod でグループに追加

アクセス出来ないときはパーミッションをいじるよりもグループをいじったほうが確実だね。

usermod -aG gitlab-wwwdata www-data

これで試してみる

nc でアクセス出来るから試す例

echo "GET /" | sudo  pkexec --user www-data nc -U   /var/opt/gitlab/gitlab-workhorse/socket
HTTP/1.1 400 Bad Request
Content-Type: text/plain; charset=utf-8
Connection: close

400 Bad request が正しく返ってくるので通信できることがわかった。これでnginx の設定が間違ってないことが確認できて安心。

2018-02-03 追記

traditional な nc ( netcat ) は -U オプションが存在しないので、invalid オプションになる。

/bin/nc.openbsd

nc: invalid option -- 'U'
nc -h for help

BSDパッケージのnetcat をインストールする必要があった。

apt install netcat-openbsd

参考資料

https://unix.stackexchange.com/questions/26715/how-can-i-communicate-with-a-unix-domain-socket-via-the-shell-on-debian-squeeze

ファイルを指定バイトコピーする(テスト用に壊れたファイルを作る)

zip が正しく転送できてない実験をしてみたかった

zip ファイルをアップロードしたり、バックアップしたりしてて、「ファイルが壊れた」のを検出したりしたかった。状況を再現したいなと思ってもそう簡単に壊れたりはしないので、壊れたファイルを作る必要がああった。

壊れたファイルを作る → dd

壊れたファイルを作るには、ファイルに0バイトを書き込んで壊したり、半分にちぎったり、変なバイトを書き込む。

これをやるには cp などのコマンドでは出来ないので、 dd コマンド を使うことになる。Cやpythonruby でfopenして書いても良いんだけど、dd コマンドが一番楽だと思う。

dd でファイルをコピーする。

最初に dd でファイルをコピーして、使い方を確認しておく

takuya@Desktop$ dd if=test.zip of=test.safe.zip
0+1 records in
0+1 records out
438 bytes copied, 0.000324 s, 1.4 MB/s
takuya@Desktop$ md5sum  test*.zip
48949110457174e7f10541080235174b  test.safe.zip
48949110457174e7f10541080235174b  test.zip

壊れたzip にする。( コピーを途中で中断した

先頭から400バイトを読み込んで、残りをコピーぜずに、中断された状況を作ってみる。

takuya@Desktop$ dd if=test.zip of=test.corrupted.zip bs=1 count=400
400+0 records in
400+0 records out
400 bytes copied, 0.00151 s, 265 kB/s

結果を確認

takuya@Desktop$ md5sum  test*.zip
7eeef77e910c3a770c557e3bb9d3d8a1  test.corrupted.zip
48949110457174e7f10541080235174b  test.zip

壊れたことを確認する。 unzip しようとしても、return code = 9 が帰ってきて、異常終了したことが分かる。

takuya@Desktop$ unzip -t test.corrupted.zip  ; echo $?
Archive:  test.corrupted.zip
  End-of-central-directory signature not found.  Either this file is not
  a zipfile, or it constitutes one disk of a multi-part archive.  In the
  latter case the central directory and zipfile comment will be found on
  the last disk(s) of this archive.
unzip:  cannot find zipfile directory in one of test.corrupted.zip or
        test.corrupted.zip.zip, and cannot find test.corrupted.zip.ZIP, period.
9

ただしこの状態でも zip のエントリ一覧は取れたりする・・・だから壊れたことを再現できるよね。

takuya@Desktop$ lsar test.corrupted.zip  ; echo $?
test.corrupted.zip: Zip
tet/
tet/a
tet/b
0

変なバイトを書いてしまった

最初に、変なバイトを書き込むファイルを用意する。

takuya@Desktop$ cp test.zip test.wrong-byte.zip

400 バイト目から、30バイトのZEROを書き込んで壊す。

takuya@Desktop$ dd if=/dev/zero of=test.wrong-byte.zip bs=1 skip=400 count=30
30+0 records in
30+0 records out
30 bytes copied, 0.000153 s, 196 kB/s

ファイルが壊れたことを確認してみる

takuya@Desktop$ unzip test.wrong-byte.zip -t
Archive:  test.wrong-byte.zip
  End-of-central-directory signature not found.  Either this file is not
  a zipfile, or it constitutes one disk of a multi-part archive.  In the
  latter case the central directory and zipfile comment will be found on
  the last disk(s) of this archive.
unzip:  cannot find zipfile directory in one of test.wrong-byte.zip or
        test.wrong-byte.zip.zip, and cannot find test.wrong-byte.zip.ZIP, period.

これで、ファイルが壊れたりHDDが壊れて、ファイルが正しく転送できなかったとかプログラマ(わたし)がアホで、ファイルの転送時のネットワーク・エラー処理が甘く変なファイルが作っちゃったとか事件を再現してソレに対応した回復プログラムを作れる実験出来ると思った。

関連資料

Keychainでパスワードを確認するのは右クリックで!

キーチェーンにパスワードを全部入れてる。

キーチェーンはパスワードの管理ツールとしてとても優秀で。

OSにバンドルされてる所が更に魅力的なんです。

パスワードを入手するには、ダブルクリックで開くしか無いと思ってたら。

右クリックで良かったんです。

f:id:takuya_1st:20170818222017p:plain

取得したいパスワードを「クリップボード」に入れるのであとは、ブラウザやアプリ側で貼り付けるだけ

キーチェーンで項目を右クリック

右クリックしたらmacOSのパスワードを聞かれるので、MacからKeychainsに許可を与えればクリップボードにパスワードが降ってくる。楽ちん。

キーチェーン非対応なアプリが困る。

チャットワークとかいうクソアプリが対応してないのでブラウザでログインしなくちゃいけないわけですが。Mac app Store のアプリはパスワードを使えたと思うんだけど・・・なんでログインだけ毎回入れなきゃならないんだろう。 oAuth でブラウザに転送してくれたら良いのに。アプリ内でログインなんて手間なだけだろ。。。

ファイルを更新したら同期したい。

ファイルを更新したら、転送したい。

php のプロジェクトってちまちま転送してると、面倒くさいんですよね。ファイル監視してrsync するのに、grunt とか持ち出すのも馬鹿馬鹿しい。

かといって、サーバーにログインしてvim で編集するとIDE使えないし、コーディング規約を守るに自動整形が使えない。かといって、SFTPアクセスでエディタで開いて編集するのもかったるい。

考えられる選択肢

他になんか有る?

選択肢 面倒なところ
unison バージョンを揃える }
lsyncd 設定ファイルとサーバ側への導入
sshfs 遅い, FUSE導入面倒くさい、オフラインで困る
NFS 認証と導入設定とメンテが面倒、ポートも面倒
dropbox アカウントと課金、同期遅い
git commit/push/push をfsevent でやると本末転倒

ファイル更新イベントでrsync起動

選択肢としてやっぱりこれしかないのかな。ファイル更新のイベント通知をOSから受け取って、更新されたファイルだけを転送したい。 すると、 ファイル更新イベント + rsync の組合せが楽チンで無難な選択肢になるわけです。

作った

python でファイル更新イベントを監視して、ファイル更新がきたら転送する

ruby で書いたけど、ruby ダメだ。python のwatchdog で書き直した。

IntelliJがファイル保存同時に .idea/ を更新するので IDEがファイル更新イベントを作りまくるのでイベント検出後数秒スリープしてその間のイベントを無視するようにした。これで ファイル更新されたあとの プリプロセッサでイベント拾いまくる事が簡単に防げると思う。

#!/usr/bin/env python3

import sys
from watchdog.observers import Observer
from watchdog.events import PatternMatchingEventHandler
from subprocess import Popen
import shlex
import time


class SyncUpload( PatternMatchingEventHandler ) :

    def __init__(self,*args, **kwargs):
        super(SyncUpload,self).__init__(*args,**kwargs)
        self.prcs = None

    def start(self, path ):
        self.watch_path  = path
        observer = Observer()
        observer.schedule( self, path, recursive=True )
        observer.start()

        try:
            observer.join()
        except KeyboardInterrupt:
            observer.stop()
        except:
            observer.stop()

    def on_any_event( self, evt ):
        if self.prcs and  self.prcs.poll() == None : # 実行中ならキャンセルする
            pass
        else:
            time.sleep(1)
            # cmd = "bash -c 'for  i in {1..3} ; do echo 1 ; sleep 1 ; done; ' "
            cmd = "rsync -avz  '%s'   server:path/to/dir/ " % self.watch_path
            self.prcs = Popen( shlex.split(cmd) )




if __name__ == '__main__':
    path = sys.argv[1] if len( sys.argv ) > 1 else './'

    obj = SyncUpload( ['*.php'] )
    obj.start( path )

過去に試した似たようなもの

.net + python

オレオレDropBoxをrsyncで作る。 - それマグで!

lsyncd

lsyncd を使ってWinSCP的なリアルタイム同期を実現する.使い方 - それマグで!

FUSE ssh

http://takuya-1st.hatenablog.jp/entry/20111118/1321594453

他にも unison があるけど、unison はバージョンを併せないと動作しないのでめっちゃ面倒くさい。

lsyncd は片方向で使うのには、面倒だと思う、特に設定ファイルとサーバー側導入が面倒くさい。

mac os が /tmp に wifi-**.log を大量に作る

/tmp のサイズがやけに大きい

しらべたら、 /tmp の中に wifi ログって言うファイルが300くらいあった。なんでや。。。

ログをやめさせる

sudo wdutil log -wifi

これでログを取らなくなるので、静になる。

参考資料

https://superuser.com/questions/1064351/when-tmp-wifi-log-will-show-up-and-how-can-i-stop-it