cron の実行結果をメールを送信するとき、結果の1行目をタイトルにする

2024/10/05 15:32 Linux

crontab の MAILTO にメールアドレスが指定されているとき、cron job の実行によって標準出力に出力があればその内容がメール送信されますが、そのときの Subject は job のコマンドの文字列となります。これだと、メールのタイトルとしてはわかりにくい(メールの内容を自然言語で説明しているものではない)ものになります。

そこで、標準出力の1行目を Subject に指定する方法を考案しました。

 | ( msg=$(cat); test -z "$msg" && exit; echo "$msg" | mail -s "`echo \"$msg\" | awk 'NR==1{printf $0}'`" "$MAILTO"

これをコマンドの右側に追記します。

具体的には crontab で次のように記述します。

1 2 * * * (echo "Disk consumption `date --iso-8601=minutes`"; df -h) | ( msg=$(cat); test -z "$msg" && exit; echo "$msg" | mail -s "`echo \"$msg\" | awk 'NR==1{printf $0}'`" "$MAILTO" )

これで毎日 2:01 am に Subject が 'Disk consumption (日付+時刻)' であるメールが届きます。この例だと mail コマンドの -s オプションに直接記述すればよいのであまりありがたみがありませんが、外部のスクリプトを呼び出すときや、出力が1行のみのコマンドを実行させるときには役に立ちます。

なお crontab で SHELL と PATH が次のように指定されているのが前提です。

SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

mail コマンドは mail (GNU Mailutils) 3.17 を使用しています。

radiko 録音予約ツール

2024/10/09 15:34 LinuxPerl
radiko でインターネット配信されるラジオ番組を、指定した時刻に予約録音するツールを制作しました。

録音には うる。 氏による radish (https://github.com/uru2/radish) を利用しました。
通常では radiko そのままの m4a ファイルで保存されますが、当ツールでは録音後に m4a -> mp3 変換を掛けます。この変換を無効化することもできます。

なお当ツールは radiko 限定としましたが、radish は radiko 以外にも NHK らじる★らじる・リスラジ他多数のネットラジオに対応したソフトです。すばらしい成果を公表してくださいましたことに感謝いたします。

ソースファイル

動作要件

  • Linux など
  • radish が単独で正常に動作していること(パスの通っている場所に配置してください)
  • at (ジョブの遅延実行とバッチ処理) がインストールされていること。

実行方法の例

当ツール rec-radiko.pl を実行権をつけて、パスの通っている場所 (/usr/local/bin/ など) に配置して、
$ rec-radiko.pl [-c|--check] [-n|--no-conversion-to-mp3] <放送局ID> <録音開始日> <録音開始時刻> <録音長(分)> <タイトル>
のように実行してください。
-c または --check任意atコマンドを発行せずに、コマンドの内容を表示します。
-n または --no-conversion-to-mp3任意録音後の mp3 形式への変換をしません。
<放送局ID>必須放送局ID
<録音開始日>必須録音開始する日付を YYYY-MM-DD 形式で指定します。 例: 2024-09-02
<録音開始時刻>必須録音開始する時刻を24時間制で hhmm または hh:mm 形式で指定します。 例: 305, 0305, 3:05, 03:05
<録音長(分)>必須録音の長さを分単位で指定します。 例: 61
<タイトル>必須タイトルを指定します。

環境変数 RADIKO_SAVE_TO に保存先のディレクトリを指定します。
~/.bashrc などに
export RADIKO_SAVE_TO=/var/radiko/save/to
のように追記すればよいでしょう。

放送局ID の確認方法

 $ radi.sh -l | perl -ne 'print if /radiko/../^$/'
を実行すると確認できます。

補足

録音時に f-radiko.smartstream.ne.jp (203.211.199.181) からこちら向きの通信 (TCP/40000台Port宛て) が来るときがあるので、拒絶しないようにします。
拒絶すると録音ができませんでした。ただし必ず来るわけではないです。(しくみがよくわかっていない)

2024-09-11対策済み: at の落とし穴 (?) セット時のカレントディレクトリがなくなってしまったときの問題

このツールでタイマー録音をセットしたのに、録音に失敗するケースがありました。
rec-radiko.pl を実行した時点のカレントディレクトリを削除して(あるいは名前変更して)しまうとダメなようでした。
at -c <job番号> で確認してみると
cd /home/*****/aaaaa/bbbbb || {
         echo 'Execution directory inaccessible' >&2
         exit 1
}
のような記述があって、at を読んだときのディレクトリが存在しなくなると失敗させるようになっていました。

Windows 起動後, ネットワーク接続が安定するまで動作を待つためのプログラム

2024/02/09 19:23

Windows 起動時のスタートアップ処理として、ネットワークドライブにドライブレターを割り付けるバッチファイル (中身は net use コマンドなど) を呼び出しているのですが、思いのほかネットワーク接続の確立に時間がかかり、動作に失敗してしまうことがあります。バッチファイルから呼び出す形で、ネットワーク接続が安定するまで次のコマンドの実行を遅延させるプログラムを書きました。

ソースコード waitnet.vb

' Copyright 2023 FUKUDA Satomi (https://satomichan.jp/)
' 
' Licensed under the Apache License, Version 2.0 (the “License”);
' you may not use this file except in compliance with the License.
' You may obtain a copy of the License at
' http://www.apache.org/licenses/LICENSE-2.0
' 
' Unless required by applicable law or agreed to in writing, software
' distributed under the License is distributed on an “AS IS” BASIS,
' WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
' 
' See the License for the specific language governing permissions and
' limitations under the License.

Public Module WaitNet
    Public Function Main(args As String()) As Integer
        'コマンドライン引数
        If args.Length <> 4 Then
            Console.WriteLine("USAGE:  waitnet <host> <port> <timeout> <retry>")
            Console.WriteLine()
            Console.WriteLine("ex)  waitnet.exe www.nhk.or.jp 80 2 3")
            Return 255
        End If

        Dim host    As String  = args(0)
        Dim port    As Integer = Integer.parse(args(1))
        Dim timeout As Integer = Integer.parse(args(2))
        Dim retry   As Integer = Integer.parse(args(3))

        Dim tcp As New System.Net.Sockets.TcpClient



        ' 接続
        Dim IsConnectSuccess As Boolean
        Do
            IsConnectSuccess = true
            Try
                Dim task = tcp.ConnectAsync(host, port)
                If Not task.wait(timeout * 1000) Then
                    IsConnectSuccess = false
                End If
            Catch ex As System.Exception
                IsConnectSuccess = false
            End Try

            If IsConnectSuccess Then Exit Do
            If retry = 0 Then Exit Do

            Console.WriteLine("ReTry: More " & retry & " times To Go.")
            retry = retry - 1
            System.Threading.Thread.Sleep(5000)
        Loop While retry >= 0



        ' 結果
        Console.WriteLine("IsConnectSuccess: " & IsConnectSuccess)
        If IsConnectSuccess Then
            Return 0
        Else
            Return 1
        End If

    End Function
End Module

VB.NET で書かれていて、Windows 附属のコンパイラ (vbc.exe) でコンパイル出来ます。

コンパイルのしかた (例)

>C:\Windows\Microsoft.NET\Framework64\v4.0.30319\vbc.exe waitnet.vb
Microsoft (R) Visual Basic Compiler version 14.8.9037
for Visual Basic 2012
Copyright (c) Microsoft Corporation.  All rights reserved.

This compiler is provided as part of the Microsoft (R) .NET Framework, but only supports language versions up to Visual Basic 2012, which is no longer the latest version. For compilers that support newer versions of the Visual Basic programming language, see http://go.microsoft.com/fwlink/?LinkID=533241


>

ネットワーク接続が安定するまで遅延実行させたい処理の書き方 (バッチファイルの例)

@echo off
C:\waitnet.exe 192.168.1.1 445 5 10
if ERRORLEVEL 1 goto ERR

net use N: \\192.168.1.1\nas passwwww /user:user2

:ERR
exit

数式参照先シフト Excel など表計算ソフト用 数式参照先セルの座標を必要な分だけ上下左右にずらした式を得るためのツール

2023/12/26 12:42

Excel などの表計算ソフト利用時に、数式内で参照しているセルの座標を必要な分だけ上下左右にずらしたいときがあります。一つや二つならばマウスでドラッグすることで容易にずらせますが、対象の数が多いと大変です。そこで、この作業を簡単に行えるツールをつくりました。

Excel などから数式をコピーして次のテキストボックスに貼り付けて、移動する数を指定し「実行」ボタンを押します。そうするとその下のテキストボックスに移動後の数式が現れるので、それを全て選択してコピー、Excel などに戻り先ほどコピーしたのと同じ場所で貼り付けをします。絶対参照のときにもシフトするかどうかはチェックボックスで選択できます。

JavaScript で実装しています。入力された数式などのデータはどこにも送信せず、いまこのページをご覧のコンピュータ内のみで処理しています。

ソース (ここに Excel から数式を貼り付ける)



行 増分 下へセル (上へ移動させる場合はマイナス値を入力)  
列 増分 右へセル (左へ移動させる場合はマイナス値を入力)  

結果 (ここから数式を Excel にコピーする)


数式のコピーのしかた

Excel での 数式のコピーのしかた

例えば Excel だと、①「数式」メニュー、②「数式の表示」を順にクリックするとセル内に数式が表示されるので、必要な範囲をドラッグで選択して、右クリック・メニューから「コピー」をします。

サブルーチンの名前付きパラメータでデフォルト値を用意する方法

2023/03/15 21:17 Perl
Joseph N. Hall ほか著『Effective Perl 第2版』(2015, 翔泳社)(https://www.shoeisha.co.jp/book/detail/9784798139814) の p.161 「項目47 名前付きパラメータを渡すにはハッシュを使おう」で、パラメータとデフォルト値を組み合わせるのに
@param { keys %input } = values %input;
を使っていたが、別の方法もあったと記憶していたので、簡単に確認した。


ソース
use strict;
use warnings;
use Data::Dumper;

my %default = (
    a => 100,
    b => 101,
    c => 102,
    d => 103,
);
print Dumper \%default;

my %param = (
    a => 200,
    c => 201,
);
print Dumper \%param;

%param = (%default, %param);
print Dumper \%param;

実行結果
$VAR1 = {
          'c' => 102,
          'd' => 103,
          'a' => 100,
          'b' => 101
        };
$VAR1 = {
          'a' => 200,
          'c' => 201
        };
$VAR1 = {
          'b' => 101,
          'a' => 200,
          'c' => 201,
          'd' => 103
        };

この書籍のコードのような、ハッシュB の内容でハッシュA を上書きするような使い方では、
my %param = (...);
...
@param { keys %input } = values %input;

my %param = (...);
...
%param = (%param, %input);
は等価であることが確認できた。

オーダーメイド栄養価計算シート生成サービス Nucalgen について

2022/03/08 3:45
オーダーメイド栄養価計算シート生成サービス Nucalgen を公開しました。
この CGI のバックで動かしている Excel ファイル生成プログラムは、 Java で書きました。
ソースコードは GitWeb で公開しています。

ライセンス

Copyright 2020-2022 FUKUDA Satomi (https://satomichan.jp/)

Licensed under the Apache License, Version 2.0 (the “License”);
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an “AS IS” BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

See the License for the specific language governing permissions and
limitations under the License.

実行方法の例

java -jar nucalgen.jar -std-food-comp-table 20201225-mxt_kagsei-mext_01110_012.xlsx [-use-processed-table] -columns columns.xml  -output output.xlsx  -lines 20 -bright-colored-vegetables-list bright-colored-vegetables.xml [-sheets 朝食 昼食 夕食 集計] [-addition addition.xml] [-set-protect]
-std-food-comp-table <filename>必須日本食品標準成分表 Excel ファイル
-use-processed-table任意日本食品標準成分表 Excel ファイルの加工をしない
-columns <filename>必須列定義ファイル
-output <filename>必須出力ファイル
-lines <n>必須行数
-bright-colored-vegetables-list <filename>必須緑黄色野菜定義ファイル
-sheets <sheet_name_1> <sheet_name_2> ... <sheet_name_n> <sheet_name_sum>任意(複数可)複数シート(食事区分+集計)を生成する
-addition <filename>任意(複数可)付加行構成ファイル
-set-protect任意入力可能セル(「食品番号」「摂取量」)以外のセルをロックする


続きを読む

3人対戦ゲームの試合数・対戦表 / 組み合わせ(数え上げ)問題を線形計画問題ソルバ GLPK を使って解く

2021/07/29 19:01 整数計画問題
数学(大学の教養科目)でこんな問題がありました(文章は変えてあります)。
・3人で行うゲームがある
・9人が参加する
・各プレイヤーは4回だけプレイできて、さらに他のすべてのプレイヤーとちょうど1回ずつプレイする
・このような条件をみたすゲームの個数(=試合数)は何通りあるか、対戦表は作れるか
数え上げ問題なのですが、この問題を整数計画問題として(もともと数え上げ問題だったものを整数計画問題に「擬態」して、それ用のソルバで解けるようにして) GLPK (Gnu Linear Programming Kit) を使って解いてみたので、これで正解なのか自信がありませんが(なんだか A+ の成績はいただけたけど、正解したとは限らないし・・・、コロナ禍のもと対面授業ではなかったので質問の機会がなかったのです)、私なりの解答を披露したいと思います。

#Yahoo!知恵袋 でも、同じ問題の答えを聞いている人がいました(こちらこちら)。
#前者の回答例は、私の解答での m02,m12,m22,m23,m30,m46,m47,m51,m63,m66,m74,m76 パターンで、対戦表では No. 352 にあたります。
#似てるけどちょっと違う出題に、数学の部屋『3人ゲームのリーグ戦』の「問題1」があります。

途中、GLPK を何百回も繰り返して実行する箇所がありますので、そういうところは perl スクリプトで自動実行しています。

答案

まず、9人に1,2,3,・・・,9と番号を付ける。
9人のうち3人でゲームをするから、その組み合わせは {}_9 \mathrm{C}_3 で、84通りある。
この組み合わせにも番号を付け、それぞれ m01, m02, ..., m84 と表す。
一覧は次の通り。

続きを読む

2020/04/05(日)mplayer用のPlayListを生成する

2020/11/03 11:32
Perl で書きました。Linux 等向けの mplayer に読ませるために、カレントディレクトリ以下の音楽ファイル(.mp3/.wma)があるディレクトリに、プレイリストを生成していきます。
「ディレクトリを再帰的にたどりファイル一覧を取得したい その1 - Perl - とあるエンジニアの闇歴史帳」(http://tech.katsubemakito.net/perl/dir_recursion1) を参考にさせていただきました。

音楽ファイルは文字コード順で並び替えられるのが前提(例: 00_zzz.mp3 , 01_yyy.mp4 , ...)です。

ソースはこちら。

続きを読む