7-Zipでバックアップ元フォルダとアーカイブの中身を同期したい

Windows環境において、毎日、特定フォルダを7z形式でバックアップしたかったが、毎回フルバックアップのようにアーカイブを作成するのではなく、差分だけ処理させたかった。

オプションを調べたところ、以下の2つで解決した。
https://7-zip.opensource.jp/chm/cmdline/switches/update.htm
https://superuser.com/questions/528232/synchronizing-files-using-7-zip-and-the-cli

以下の部分。

My example of "u -uq0" is identical to "u -up1q0r2x1y2z1w2", because only the "q0" is different from what "u" usually does.

公式ヘルプによると、u と -uq0 を併用すると、「Synchronize」のオプションを指定した事になるとの説明。
(一覧表の u (Update) / Synchronize の行を参照)


考え方としては、

  • 7-zip で u(update)コマンドを使用し、-uq0 のオプションを付加
  • ソリッド圧縮すると処理が遅くなるため、-ms=off としておく

をベースに、他に必要なオプションを付加して、次のようなコマンドで同期が実現できる。

7z.exe u $CompressionLevel $LogLevel $ExcludeLists -ms=off dst_file.7z -uq0 $SrcFolder

ここで、各変数は以下の通り。
$SrcFolder:ソースフォルダ
$CompressionLevel:-mx1 (fastest) ... -mx9 (ultra) の圧縮レベルを指定。
$ExcludeLists:除外ディレクトリを指定(例:-xr!"Thumbs.db" -xr!"*.tmp")
$LogLevel:-bb0~-bb3,(少~多)を指定。未指定の場合は、-bb0:なし、になる。
https://7-zip.opensource.jp/chm/cmdline/switches/method.htm
https://7-zip.opensource.jp/chm/cmdline/switches/exclude.htm
https://7-zip.opensource.jp/chm/cmdline/switches/bb.htm


動作を試すと、次のようになる。
1回目:すべてアーカイブに追加される(除外指定したものは対象外)
2回目以降
 - アーカイブ内に無いファイルは、新しく追加される
 - ソース側のファイルのタイムスタンプが新しい場合は、アーカイブ内へ上書き更新される
 - アーカイブ内にあり、ソース側に無いファイルは、アーカイブ内から削除される
 - アーカイブ内とソース側の両方にあり、ソース側の方がタイムスタンプが古い場合は更新されない(上書きされずスキップ)

PHPでImagickのバージョンに関する警告が発生する

いつから発生していたのか不明だけど、PHPStanやpeclなどを実行した時に次のような警告が出るようになった。

PHP Warning:  Version warning: Imagick was compiled against ImageMagick version 1692 but version 1693 is loaded. Imagick will run but may behave surprisingly in Unknown on line 0

コンパイルされたImageMagickのバージョン(1692)とロードされたImageMagickのバージョン(1693)が異なるという事らしい。


環境は以下の通り。
AlmaLinux8
PHP 7.4.33
PHPのimagickはpeclを利用、imagickライブラリはdnfで導入したもの


imagickはpeclで追加していたので、現状を確認

# pecl list
PHP Warning:  Version warning: Imagick was compiled against ImageMagick version 1692 but version 1693 is loaded. Imagick will run but may behave surprisingly in Unknown on line 0
Installed packages, channel pecl.php.net:
=========================================
Package Version State
imagick 3.7.0   stable


peclのアップグレードを試しても、既に最新らしい

# pecl upgrade imagick
PHP Warning:  Version warning: Imagick was compiled against ImageMagick version 1692 but version 1693 is loaded. Imagick will run but may behave surprisingly in Unknown on line 0
Nothing to upgrade


peclインストール時と関連ライブラリのバージョンが不整合になっているのが原因ぽいので、再インストールしてみることにした。

ひとまずアンインストール

# pecl uninstall imagick
PHP Warning:  Version warning: Imagick was compiled against ImageMagick version 1692 but version 1693 is loaded. Imagick will run but may behave surprisingly in Unknown on line 0
Unable to remove "extension=imagick.so" from php.ini
uninstall ok: channel://pecl.php.net/imagick-3.7.0

再びインストール

# pecl install imagick
PHP Warning:  PHP Startup: Unable to load dynamic library 'imagick.so' (tried: /usr/lib64/php/modules/imagick.so (/usr/lib64/php/modules/imagick.so: cannot open shared object file: No such file or directory), /usr/lib64/php/modules/imagick.so.so (/usr/lib64/php/modules/imagick.so.so: cannot open shared object file: No such file or directory)) in Unknown on line 0
・・・
Build process completed successfully
Installing '/usr/lib64/php/modules/imagick.so'
Installing '/usr/include/php/ext/imagick/php_imagick_shared.h'
install ok: channel://pecl.php.net/imagick-3.7.0
configuration option "php_ini" is not set to php.ini location
You should add "extension=imagick.so" to php.ini

手抜きして、アンインストール前にPHPで .soをロードする設定を消さずに作業したため別な警告が出ているが、無視。

再インストールで、最初に出ていた警告も出なくなった。

PostgreSQL 9.x と 12.x のSQL非互換の一例

CentOS 7のCGIをRocky/Alma8へ移行すると、PostgreSQLのバージョン非互換に遭遇することがある。
その一例。

バージョン情報

CentOS 7 : PostgreSQL 9.2.24
Rocky/Alma8: PostgreSQL 12.18

UPDATE文のROWキーワード

これは、Cent7まではOKで、Rocky/Alma8以降はNGになる例。

UPDATE table_name SET (clm1) = (val1) WHERE ....
ERROR:  複数列のUPDATE項目のソースは副問合せまたはROW()式でなければなりません

英語の場合のエラーメッセージの場合は以下のように表示される。

ERROR:  source for a multiple-column UPDATE item must be a sub-SELECT or ROW() expression


なお、カラムが複数ならRocky/Alma8でも問題ない。
SETの後に ( ) でカラムを指定する際は、複数でなければならないらしい。

UPDATE table_name SET (clm1, clm2) = (val1, val2) WHERE ....

あるいは、ROW というキーワードを付けても動作する。

UPDATE table_name SET (clm1) = ROW (val1) WHERE ....


UPDATE table_name SET clm1=val1, clm2=val2 WHERE ....
のように書いていれば問題ないが、参考にした書籍かサイトが古いと上記のようになってしまうのかもしれない。


以下の「問い合わせ」の説明が該当箇所
PostgreSQL 10 に関する技術情報

公式マニュアルの該当箇所
https://www.postgresql.jp/document/9.2/html/sql-update.html
https://www.postgresql.jp/document/12/html/sql-update.html


to_date などで不正な日付のチェックが厳格化

こちらは、PostgreSQLの日付関数が厳格になったもの。

Cent7(PG 9.x)

db=> SELECT TO_CHAR(TO_DATE('20240230', 'YYYYMMDD'), 'YYYY-MM-DD');
  to_char
------------
 2024-03-01

Rocky/Alma8以降(PG 12)

db=> SELECT TO_CHAR(TO_DATE('20240230', 'YYYYMMDD'), 'YYYY-MM-DD');
ERROR:  日付時刻のフィールドが範囲外です: "20240230"


PG 9.xまでは、存在しない2024年2月30日を指定した際に3月1日で返ってきていたが、PG 10以降ではエラーを返すようになった。


該当箇所は、PostgreSQL 10 リリースノートの以下の部分。

・to_timestamp()とto_date()が範囲外の入力フィールドを拒否するようにしました。 (Artur Zakirov)

openldap-serversパッケージの更新でエラーになる

AlmaLinux8 にopenldap-serversパッケージがインストールされた環境で、dnf upgradeしたらエラーが発生。

# dnf upgrade
エラー:
 問題: package openldap-servers-2.4.46-18.el8.x86_64 from @System requires openldap(x86-64) = 2.4.46-18.el8, but none of the providers can be installed
  - cannot install both openldap-2.4.46-19.el8_10.x86_64 from baseos and openldap-2.4.46-18.el8.x86_64 from @System
  - cannot install both openldap-2.4.46-19.el8_10.x86_64 from baseos and openldap-2.4.46-18.el8.x86_64 from baseos
  - パッケージの最良アップデート候補をインストールできません openldap-2.4.46-18.el8.x86_64
  - インストール済パッケージの問題 openldap-servers-2.4.46-18.el8.x86_64
(競合するパッケージを置き換えるには、コマンドラインに '--allowerasing' を追加してみてください または、'--skip-broken' を追加して、インストール不可のパッケージをスキップしてください または、'--nobest' を追加して、最適候補のパッケージのみを使用しないでください)


インストールされたバージョンを確認

# rpm -qa | grep openldap
openldap-clients-2.4.46-18.el8.x86_64
openldap-servers-2.4.46-18.el8.x86_64
openldap-2.4.46-18.el8.x86_64


状況からすると、

  • openldap-2.4.46-19(クライアント)をインストールできない
  • openldap-servers-2.4.46-18 の動作には、openldap(x86-64) = 2.4.46-18 が必要
  • クライアントをv19へ更新する際、openldap-serversパッケージでクライアントのv18が必要なので矛盾する

という事らしい。

openldap-serversも19へ一緒に更新できれば依存関係をクリアできるが、19が見つからない状況。

openldap-servers パッケージはpowertoolsリポジトリからインストールしていたので、以下のようにして解消。

# dnf --enablerepo=powertools upgrade

忘れてしまうので、
/etc/yum.repos.d/almalinux-powertools.repo
で以下のように変更。

[powertools]
- enabled=0
+ enabled=1

これで「--enablerepo=powertools」を付けなくても有効化される。


関連記事
shobon.hatenablog.com

CentOS 7のyumコマンドでCentOS-Vault.repoを参照する

CentOS 7のサポート期限が2024/6だったので、cronからエラーメールが届くようになった。

/etc/cron.hourly/0yum-hourly.cron:

Could not retrieve mirrorlist http://mirrorlist.centos.org/?release=7&arch=x86_64&repo=os&infra=stock error was
14: curl#6 - "Could not resolve host: mirrorlist.centos.org; 名前またはサービスが不明です"
Could not retrieve mirrorlist http://mirrorlist.centos.org/?release=7&arch=x86_64&repo=extras&infra=stock error was
14: curl#6 - "Could not resolve host: mirrorlist.centos.org; 名前またはサービスが不明です"
Could not retrieve mirrorlist http://mirrorlist.centos.org/?release=7&arch=x86_64&repo=updates&infra=stock error was
14: curl#6 - "Could not resolve host: mirrorlist.centos.org; 名前またはサービスが不明です"

よく利用させて頂くrikenのリポジトリへ行くと、readmeだけ。(大変お世話になりました)
https://ftp.riken.jp/Linux/centos/7/


解決策として、リポジトリを https://vault.centos.org/ へ向けるよう変更する。

yumのリポジトリのディレクトリをバックアップ

# cp -r /etc/yum.repos.d /etc/yum.repos.d.2024-06-30

次に、2つの手順を行う。

(1)/etc/yum.repos.d/CentOS-Base.repo にて、ミラーリポジトリを無効にする。

[base][updates][extras] のディレクティブに、enabled=0 を追加する。
[centosplus] の初期値は 0 になっているが、1 で利用していた場合は 0 にする。

こんな感じで。

[base]
name=CentOS-$releasever - Base
mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=os&infra=$infra
#baseurl=http://mirror.centos.org/centos/$releasever/os/$basearch/
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7
enabled=0

(2)/etc/yum.repos.d/CentOS-Vault.repo を有効化する

もし、このファイルの末尾に、7.9.2009 の定義が無い場合は、それより前のバージョンの記述を参考に追記する。
7.9.2009 のbase/updates/extras の項目において、 enabled=1 とする。
centosplus は、enabled=0 or 1 どちらか用途に応じて設定。

こんな感じで。

# C7.9.2009
[C7.9.2009-base]
name=CentOS-7.9.2009 - Base
baseurl=http://vault.centos.org/7.9.2009/os/$basearch/
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7
enabled=1

もし、利用しているCent7が 7.9 以外の場合は、そのバージョンのリポジトリを有効化する。


キャッシュを削除

# yum clean all

updateなどでリポジトリへのアクセスを確認

# yum  update
読み込んだプラグイン:fastestmirror
Determining fastest mirrors
C7.9.2009-base                                   | 3.6 kB     00:00
C7.9.2009-extras                                 | 2.9 kB     00:00
C7.9.2009-updates                                | 2.9 kB     00:00
(1/4): C7.9.2009-base/x86_64/group_gz              | 153 kB   00:00
(2/4): C7.9.2009-extras/x86_64/primary_db          | 253 kB   00:00
(3/4): C7.9.2009-base/x86_64/primary_db            | 6.1 MB   00:00
(4/4): C7.9.2009-updates/x86_64/primary_db         |  27 MB   00:00
No packages marked for update

サポート期限までに取り逃がしたupdateがあれば、適用できる。

ついでに、自動更新のパッケージ(yum-cron)をインストールしていた場合は、停止するか削除しておく。
(サポート期限より後では新しいパッチがリリースされず、自動更新する意味がないため)


CentOS 6の時にも同じような記事を書いてた
shobon.hatenablog.com

テンプレートエンジンにおけるループ回数(index)の初期値

テンプレートエンジンでループのインデックス(現在のループ回数)を得る方法が、0 または 1 から始まる違いがあったので調べた。

主要なテンプレートエンジンだけ抜粋。

Smarty

indexは、0 から開始(1から開始するのは、@iteration)
https://www.smarty.net/docs/ja/language.function.foreach.tpl#foreach.property.index
https://www.smarty.net/docs/ja/language.function.foreach.tpl#foreach.property.iteration

Blade

Laravelのテンプレートエンジン。
indexは、0 から開始(1から開始するのは、@iteration)
https://readouble.com/laravel/8.x/ja/blade.html

PHPTAL

indexは、0 から開始(1から開始するのは、number)
https://phptal.org/manual/en/#tal-repeat

Twig

Symfonyのテンプレートエンジン。
indexは、1 から開始(0から開始するのは、index0)
https://twig.symfony.com/doc/2.x/tags/for.html#the-loop-variable

Volt

Phalconのテンプレートエンジン。
indexは、1 から開始(0から開始するのは、index0)
https://docs.phalcon.io/5.7/volt/#loop-context


indexが1から始まる場合、index0 という変数が用意されている。

シェルでコマンドの引数にハイフン2個(--)は何?

とあるサービスの起動スクリプトで、

if expr -- "${HOGE__ARGS[*]}" : '.*setuid.*' >/dev/null

といったものを見て、これ何だっけ?となったのでメモ。


これはgetoptの引数解析の仕様。

getoptのmanによると、以下のようにある。

"--" は特殊な引き数で、スキャンのモードによらず、 オプションのスキャンを強制的に終了させる。

ja.manpages.org

つまり、引数解析の終わりを示す。(これより先はオプションではない、と明示するもの)

ここでの「--」の役割は、 "${HOGE__ARGS[*]}" がハイフンから始まる場合に、exprコマンドの引数でない事を保証するためと思われる。

ただ、exprコマンドで - から始まる引数は、「--help, --version」ぐらいに思えるので、どれほど意味があるのかは謎のまま(´・ω・`)