揮発性のメモ2

http://d.hatena.ne.jp/iww/

vimで無用なインデントをさせない

vimで勝手にインデントしてしまう小さな親切を無効化する

:set noautoindent
:set nosmartindent
:set nocindent
:set indentexpr=
:set paste
noautoindent 普通のインデントを無効化
nosmartindent 賢いインデントを無効化
nocindent C言語用インデントを無効化
indentexpr= 言語ごとのインデントを無効化
paste すべてのインデントを一時無効化


stupiddog.jp
vim.fandom.com
vim-jp.org

TeraTermで、シリアルコンソールの画面サイズを変更したとき

TeratermでシリアルコンソールでLinuxに接続しているとき、画面サイズの変更は
sttyコマンドでおこなう

# stty size
24 80
# stty rows 48 columns 160
# stty size
48 160


linuxjm.osdn.jp

桁数は割とすぐ反映されるけど、行数はなんか反映されないことがある。
stty size で確認した結果となんか食い違っているときは「端末リセット」で直る

unpackは想像以上にメモリをたくさん消費する

PHPで500KB程度のバイナリファイルを1バイトずつ処理したかったので

<?
$array = unpack("C*", file_get_contents($argv[1]));
foreach($array as $a){

みたいなコードを書いていたら、メモリが足りないというエラーが出た

$ ./hoge.php hoge.bin
PHP Fatal error:  Allowed memory size of 33554432 bytes exhausted (tried to allocate 20 bytes) in /tmp/hoge.php on line 3

なんで500KBをunpackしたら32MB超えるんだよ
と思って調べたところ、本当に超えていた

<?
ini_set('memory_limit', '128M'); // テスト用にメモリを拡張
echo("読出し前 ". memory_get_usage());

$text  = file_get_contents($argv[1]);
echo("読出し後 ". memory_get_usage());

$array = unpack("C*", $text);
echo("unpack後 ". memory_get_usage());
読出し前 117924
読出し後 618204
unpack後 38715820

(38715820-618204)/500000 = 76
概算で1バイトあたり76バイト使っている。(実際には管理領域とかあるので違うけど)
じゃあstr_split()でいこうと思ったら、もっと浪費していた。(概算92バイトくらい)

しかたがないので、1文字ずつ取り出してループするように変更

<?
$text = file_get_contents($argv[1]);
$size = strlen($text);
for($i=0; $i<$size; $i++){
    $a = ord(substr($text, $i, 1));


stackoverflow.com
検索したら結構メジャーなトラブルっぽかった

feofでループするとバグる

feof() は終端まで到達していたらEOFを返すけど、終端かどうかは最後の文字の次の文字を読むまでわからない。
よって、while(!feof() みたいにループで1文字ずつ読むと、必ず最後にゴミがでる。

今までファイルを1文字ずつ読んだことなんかなかったので、初めて気づいた

<?php
$fp=fopen($argv[1],"r") or die("fopen");
while(!feof($fp)){
    $c = fgetc($fp);
    if($c===false){
        echo "ナンデ?\n";
    }else{
        echo ord($c).",";
    }
}
#include <stdio.h>

int main(int argc, char *argv[])
{
    FILE *fp;
    int c;

    fp = fopen(argv[1],"r");
    if(fp==NULL){
        perror("fopen");
        return 1;
    }
    while(!feof(fp)){
        c = fgetc(fp);
        if(c==EOF){
            printf("ナンデ?\n");
        }else{
            printf("%d,",c);
        }
    }

    return 0;
}


ググったら文句を言っている人はいっぱいいた。 PHPに至ってはマニュアルで愚痴ってる
stackoverflow.com
hnw.hatenablog.com
https://www.php.net/manual/ja/function.feof.php

udevでバックグラウンドで動くプログラムを起動する 3

USB機器を挿した契機で、ちょっと時間のかかるプログラムをバックグラウンドで起動したい。
また、抜けたら抜けたで何か起動したい。

/etc/udev/rules.d/99-local-usb.rules

# USB機器が刺さったらなんかする
ACTION=="add", SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", TAG+="systemd", ENV{SYSTEMD_WANTS}+="hoge@%E{DEVPATH}.service"

/etc/systemd/system/hoge@.service

[Unit]
Description=HOGEHOGE service %I
#After=network.target
StopWhenUnneeded=true

[Service]
Type=oneshot
ExecStart=/usr/local/bin/hoge.sh add %I
ExecStop=/usr/local/bin/hoge.sh remove %I
RemainAfterExit=true

[Install]
WantedBy=multi-user.target

systemd.unit
bugzilla.redhat.com
まず、TAG+="systemd" とした時点で ACTION=="remove"はなんやかんやで利かなくなる。
よって、addのときはsystemd経由でremoveのときは自分でRUN、などはできない。

StopWhenUnneeded

不要になったとき(addに対するremoveのとき)に自動でStopを呼ぶかどうかの設定。
これだけを有効にすると、oneshotのときは 呼び出したプログラムが正常終了した契機でも 不要扱いとなり、Stopが実行されてしまうのでもう一つ設定する。

RemainAfterExit

oneshotのとき、プログラムが正常終了しても ステータスを維持する。
これだけを有効にしても、removeに対する行動はとくに起きない。


この2つの設定をすることで刺さったときも抜けたときも別のプログラムを背後で起動できる

udevでバックグラウンドで動くプログラムを起動する 2

USB機器を挿した契機で、ちょっと時間のかかるプログラムをバックグラウンドで起動したい。
そのまま呼ぶと一瞬で殺されるので、systemdを使って起動する

/etc/udev/rules.d/99-local-usb.rules
# USB機器が刺さったらなんかする
#ACTION=="add"  , SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", RUN+="/usr/local/bin/hoge.sh"
ACTION=="add"   , SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", TAG+="systemd", ENV{SYSTEMD_WANTS}+="hoge.service"
/etc/systemd/system/hoge.service
[Unit]
Description=HOGEHOGE service
#After=network.target

[Service]
Type=oneshot
ExecStart=/usr/local/bin/hoge.sh

[Install]
WantedBy=multi-user.target


Linux でデバイスを接続している時だけ動くサービスを作る - Qiita
access.redhat.com

      •  
続きを読む