rpi-imager OSのカスタマイズ機能を理解する
rpi-imager をターミナルから実行すると非常に有用な情報を提供してくれます。
設定を変更するたびに関連する項目を処理するスクリプトをコンソールに出力します。
コンソールに表示されたスクリプトはブートフアイルシステム上に出力されます。OSをインストールする前であれば内容を確認することができます。
※このスクリプトは OS のインストールが完了すると削除されしまいます。
1 環境
1-1 検証用デバイス
- Raspberry Pi 2w
- Raspberry Pi OS (32bit) with desktop (bookworm)
2024-11-19-raspios-bookworm-armhf.img.xz
- Raspberry Pi OS (32bit) with desktop (bookworm)
1-2 開発PC
- Ubuntu 22-04 Desktop
- rpi-imager インストール済み
sudo apt-get install rpi-imager
2 OSカスタマイズ用スクリプト
2-1 SDカードのマウント
書き込み完了後のSDカードを取り外し、再度 USBに挿したときのマウント先
※1 Ubuntu では bootfs は読み取り専用、rootfs は読み書きモードでマウントされます。
※2 私の環境では /dev/sdc1 (bootfs), /dev/sdc2 (rootfs1) でした。
$ LANG=C;lsblk -e7 | grep sdc
sdc 8:32 1 59.5G 0 disk
|-sdc1 8:33 1 512M 0 part /media/yukio/bootfs
`-sdc2 8:34 1 58.9G 0 part /media/yukio/rootfs1
# bootfs に移動
$ cd $ cd /media/yukio/bootfs/
/media/yukio/bootfs$ ls -l --time-style long-iso *.sh | grep -v total
-rw-r--r-- 1 yukio yukio 2520 2024-12-19 21:27 firstrun.sh
2-2 ブート時の OSカスタマイズ用スクリプト
ブートファイルシステム (/dev/sdc1) 上に出力されたスクリプトを以下に示します。
/media/yukio/bootfs/firstrun.sh
カスタマイズ用のスクリプトと呼び出されるスクリプトを理解すると、ネットワーク接続を固定IPアドレスに設定する等の設定ファイルの作成方法がわかるようになります。
スクリプト中 imager_customスクリプトの存在チェックをしている箇所が有りますが、通常は存在するので else 側の代替処理は実行されることありません。
※imager_custom スクリプトは代替処理では出力されないファイルも出力します。
if [ -f /usr/lib/raspberrypi-sys-mods/imager_custom ]; then
/usr/lib/raspberrypi-sys-mods/imager_custom [設定項目] [設定値]
else
# 代替処理
fi
最初にスクリプト全体を下記に示します。
※ スクリプト内の SSID とパスワードは適当に加工しています。
- カスタマイズした項目
- 一般
- ホスト名を変更
- ユーザー名の変更とパスワード設定
- WiFi接続を有効化
- サービス
- SSH有効、パスワード認証
- 一般
#!/bin/bash
set +e
CURRENT_HOSTNAME=`cat /etc/hostname | tr -d " \t\n\r"`
if [ -f /usr/lib/raspberrypi-sys-mods/imager_custom ]; then
/usr/lib/raspberrypi-sys-mods/imager_custom set_hostname raspi-4-dev
else
echo raspi-4-dev >/etc/hostname
sed -i "s/127.0.1.1.*$CURRENT_HOSTNAME/127.0.1.1\traspi-4-dev/g" /etc/hosts
fi
FIRSTUSER=`getent passwd 1000 | cut -d: -f1`
FIRSTUSERHOME=`getent passwd 1000 | cut -d: -f6`
if [ -f /usr/lib/raspberrypi-sys-mods/imager_custom ]; then
/usr/lib/raspberrypi-sys-mods/imager_custom enable_ssh
else
systemctl enable ssh
fi
if [ -f /usr/lib/userconf-pi/userconf ]; then
/usr/lib/userconf-pi/userconf 'raspi' '$5$jMUnTaL7a9$3hl.a1JPfHrvoKtbZ.gFpqac1NAWoIGYG.N8Ht2J5m8'
else
echo "$FIRSTUSER:"'$5$jMUnTaL7a9$3hl.a1JPfHrvoKtbZ.gFpqac1NAWoIGYG.N8Ht2J5m8' | chpasswd -e
if [ "$FIRSTUSER" != "raspi" ]; then
usermod -l "raspi" "$FIRSTUSER"
usermod -m -d "/home/raspi" "raspi"
groupmod -n "raspi" "$FIRSTUSER"
if grep -q "^autologin-user=" /etc/lightdm/lightdm.conf ; then
sed /etc/lightdm/lightdm.conf -i -e "s/^autologin-user=.*/autologin-user=raspi/"
fi
if [ -f /etc/systemd/system/getty@tty1.service.d/autologin.conf ]; then
sed /etc/systemd/system/getty@tty1.service.d/autologin.conf -i -e "s/$FIRSTUSER/raspi/"
fi
if [ -f /etc/sudoers.d/010_pi-nopasswd ]; then
sed -i "s/^$FIRSTUSER /raspi /" /etc/sudoers.d/010_pi-nopasswd
fi
fi
fi
if [ -f /usr/lib/raspberrypi-sys-mods/imager_custom ]; then
/usr/lib/raspberrypi-sys-mods/imager_custom set_wlan 'xxxxxx2g-yyyyyy' '1234ec0f4cb652cc3873de1780a95ef8aec245c838e7ac61251c20b8ecb56789' 'JP'
else
cat >/etc/wpa_supplicant/wpa_supplicant.conf <<'WPAEOF'
country=JP
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
ap_scan=1
update_config=1
network={
ssid="xxxxx-yyyyy"
psk=1234ec0f4cb652cc3873de1780a95ef8aec245c838e7ac61251c20b8ecb56789
}
WPAEOF
chmod 600 /etc/wpa_supplicant/wpa_supplicant.conf
rfkill unblock wifi
for filename in /var/lib/systemd/rfkill/*:wlan ; do
echo 0 > $filename
done
fi
if [ -f /usr/lib/raspberrypi-sys-mods/imager_custom ]; then
/usr/lib/raspberrypi-sys-mods/imager_custom set_keymap 'jp'
/usr/lib/raspberrypi-sys-mods/imager_custom set_timezone 'Asia/Tokyo'
else
rm -f /etc/localtime
echo "Asia/Tokyo" >/etc/timezone
dpkg-reconfigure -f noninteractive tzdata
cat >/etc/default/keyboard <<'KBEOF'
XKBMODEL="pc105"
XKBLAYOUT="jp"
XKBVARIANT=""
XKBOPTIONS=""
KBEOF
dpkg-reconfigure -f noninteractive keyboard-configuration
fi
rm -f /boot/firstrun.sh
sed -i 's| systemd.run.*||g' /boot/cmdline.txt
exit 0
2-2 (1) 一般: ホスト名変更
[既定値] raspberryPi
ルートファイルシステム上の値
$ cd /media/yukio/rootfs1/etc/
# Default hostname
/media/yukio/rootfs1/etc$ cat hostname
raspberrypi
#
# hosts
/media/yukio/rootfs1/etc$ cat hosts
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
127.0.1.1 raspberrypi
ホスト名変更処理
#!/bin/bash
set +e
CURRENT_HOSTNAME=`cat /etc/hostname | tr -d " \t\n\r"`
if [ -f /usr/lib/raspberrypi-sys-mods/imager_custom ]; then
/usr/lib/raspberrypi-sys-mods/imager_custom set_hostname raspi-4-dev
else
echo raspi-4-dev >/etc/hostname
sed -i "s/127.0.1.1.*$CURRENT_HOSTNAME/127.0.1.1\traspi-4-dev/g" /etc/hosts
fi
2-2 (2) 一般: ユーザ名とパスワード
[既定値] pi
FIRSTUSER=`getent passwd 1000 | cut -d: -f1`
FIRSTUSERHOME=`getent passwd 1000 | cut -d: -f6`
if [ -f /usr/lib/userconf-pi/userconf ]; then
/usr/lib/userconf-pi/userconf 'raspi' '$5$jMUnTaL7a9$3hl.a1JPfHrvoKtbZ.gFpqac1NAWoIGYG.N8Ht2J5m8'
else
echo "$FIRSTUSER:"'$5$jMUnTaL7a9$3hl.a1JPfHrvoKtbZ.gFpqac1NAWoIGYG.N8Ht2J5m8' | chpasswd -e
if [ "$FIRSTUSER" != "raspi" ]; then
usermod -l "raspi" "$FIRSTUSER"
usermod -m -d "/home/raspi" "raspi"
groupmod -n "raspi" "$FIRSTUSER"
if grep -q "^autologin-user=" /etc/lightdm/lightdm.conf ; then
sed /etc/lightdm/lightdm.conf -i -e "s/^autologin-user=.*/autologin-user=raspi/"
fi
if [ -f /etc/systemd/system/getty@tty1.service.d/autologin.conf ]; then
sed /etc/systemd/system/getty@tty1.service.d/autologin.conf -i -e "s/$FIRSTUSER/raspi/"
fi
if [ -f /etc/sudoers.d/010_pi-nopasswd ]; then
sed -i "s/^$FIRSTUSER /raspi /" /etc/sudoers.d/010_pi-nopasswd
fi
fi
fi
[補足] FIRSTUSER と FIRSTUSERHOME を開発PCで確認すると以下のようになりました。
$ getent passwd 1000
yukio:x:1000:1000:yukio,,,:/home/yukio:/bin/bash
$ getent passwd 1000 | cut -d: -f1
yukio
$ getent passwd 1000 | cut -d: -f6
/home/yukio
2-2 (3) 一般: Wi-Fi設定
- 作成される設定ファイル
- /etc/wpa_supplicant/wpa_supplicant.conf
※代替処理では NetworkManager用のWiFi接続設定ファイルは出力しません。
- /etc/wpa_supplicant/wpa_supplicant.conf
if [ -f /usr/lib/raspberrypi-sys-mods/imager_custom ]; then
/usr/lib/raspberrypi-sys-mods/imager_custom set_wlan 'xxxxx-yyyyy' '1234ec0f4cb652cc3873de1780a95ef8aec245c838e7ac61251c20b8ecb56789' 'JP'
else
cat >/etc/wpa_supplicant/wpa_supplicant.conf <<'WPAEOF'
country=JP
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
ap_scan=1
update_config=1
network={
ssid="xxxxx-yyyyy"
psk=1234ec0f4cb652cc3873de1780a95ef8aec245c838e7ac61251c20b8ecb56789
}
WPAEOF
chmod 600 /etc/wpa_supplicant/wpa_supplicant.conf
rfkill unblock wifi
for filename in /var/lib/systemd/rfkill/*:wlan ; do
echo 0 > $filename
done
fi
2-2 (4) 一般: ロケール変更
if [ -f /usr/lib/raspberrypi-sys-mods/imager_custom ]; then
/usr/lib/raspberrypi-sys-mods/imager_custom set_keymap 'jp'
/usr/lib/raspberrypi-sys-mods/imager_custom set_timezone 'Asia/Tokyo'
else
rm -f /etc/localtime
echo "Asia/Tokyo" >/etc/timezone
dpkg-reconfigure -f noninteractive tzdata
cat >/etc/default/keyboard <<'KBEOF'
XKBMODEL="pc105"
XKBLAYOUT="jp"
XKBVARIANT=""
XKBOPTIONS=""
KBEOF
dpkg-reconfigure -f noninteractive keyboard-configuration
fi
2-2 (5) サービス: SSHの使用
if [ -f /usr/lib/raspberrypi-sys-mods/imager_custom ]; then
/usr/lib/raspberrypi-sys-mods/imager_custom enable_ssh
else
systemctl enable ssh
fi
[補足] 「公開鍵認証のみを許可する」を選択し開発PCの公開鍵を指定したときの例
※公開鍵は一部省略しています。
if [ -f /usr/lib/raspberrypi-sys-mods/imager_custom ]; then
/usr/lib/raspberrypi-sys-mods/imager_custom enable_ssh -k 'ssh-rsa AA...一部省略...@Dell-T7500'
else
install -o "$FIRSTUSER" -m 700 -d "$FIRSTUSERHOME/.ssh"
install -o "$FIRSTUSER" -m 600 <(printf "ssh-rsa AA...一部省略...@Dell-T7500") "$FIRSTUSERHOME/.ssh/authorized_keys"
echo 'PasswordAuthentication no' >>/etc/ssh/sshd_config
systemctl enable ssh
fi
2-2 (6) クリーンアップ
(1) /boot/firstrun.sh
の削除
(2) cmdline.txt から firstrun.sh 実行部分を削除する
rm -f /boot/firstrun.sh
sed -i 's| systemd.run.*||g' /boot/cmdline.txt
exit 0
2-3 カスタマイズ処理メインスクリプト
firstrun.sh スクリプトから呼び出されるスクリプト一覧
# ユーザーとパスワード設定を除く設定
/media/yukio/rootfs1/usr/lib$ tree raspberrypi-sys-mods/ | grep -v dir | grep -v ^$
raspberrypi-sys-mods/
|-- firstboot
|-- get_fw_loc
|-- i2cprobe
|-- imager_custom # ★★ シェルスクリプト
|-- init_config
|-- regenerate_ssh_host_keys
`-- sshswitch
#
# ユーザーとパスワード設定
/media/yukio/rootfs1/usr/lib$ tree userconf-pi/ | grep -v dir | grep -v ^$
userconf-pi/
|-- userconf # ★★ シェルスクリプト
`-- userconf-service
/usr/lib/raspberrypi-sys-mods/imager_custom
上記 [2-2] で呼び出しされた処理のみ抜粋します。
このスクリプトで実行している raspi-config CLI
については下記をご覧ください。
(公式) Raspberry Pi Documentation Configuration: raspi-config#raspi-config-cli
2-3 (1) 一般: ホスト名変更
raspi-config CLI
コマンドを実行してる部分が代替処理とは異なります。
set_hostname () (
if [ "$#" -ne 1 ]; then
usage set_hostname
exit 1
fi
HOSTNAME="$1"
raspi-config nonint do_hostname "$HOSTNAME" # ★この部分が代替処理と異なる
echo "$HOSTNAME" > /etc/hostname
)
2-3 (2) 一般: ユーザ名とパスワード
この処理のみ /usr/lib/userconf-pi/userconf
スクリプトを使っています。
ソースを見る限り代替処理とほぼ同じですが、最後の cancel-rename
スクリプトの中で raspi-config CLI
コマンドを実行してる部分が異なっていました。
#!/bin/sh
rename_user () {
usermod -l "$NEWNAME" "$FIRSTUSER"
usermod -m -d "/home/$NEWNAME" "$NEWNAME"
groupmod -n "$NEWNAME" "$FIRSTGROUP"
for file in /etc/subuid /etc/subgid; do
sed -i "s/^$FIRSTUSER:/$NEWNAME:/" "$file"
done
if [ -f /etc/sudoers.d/010_pi-nopasswd ]; then
sed -i "s/^$FIRSTUSER /$NEWNAME /" /etc/sudoers.d/010_pi-nopasswd
fi
}
if [ $# -eq 3 ]; then
FIRSTUSER="$1"
FIRSTGROUP="$1"
shift
else
FIRSTUSER="$(getent passwd 1000 | cut -d: -f1)"
FIRSTGROUP="$(getent group 1000 | cut -d: -f1)"
fi
NEWNAME=$1
NEWPASS=$2
if [ "$FIRSTUSER" != "$NEWNAME" ]; then
rename_user
fi
if [ -n "$NEWPASS" ]; then
echo "$NEWNAME:$NEWPASS" | chpasswd -e
fi
/usr/bin/cancel-rename "$NEWNAME" # ★ シェルスクリプト
2-3 (3) 一般: Wi-Fi設定
NetworkManager 用のWiFi接続設定ファイルを出力します。
- 出力先ディレクトリ: /etc/NetworkManager/system-connections/
- WiFi接続設定ファイル: preconfigured.nmconnection
※1 wpa_supplicant.conf は WiFi接続には使われないため作成されません。
※2 Wi-Fi接続設定ファイルは DHCPサーバーからIPアドレスを取得する仕様になっておりこの設定をOSイントール時に変更することはできません。
※3 以下のコードを参考に 有線ネットワークのIPv4 固定アドレスを設定する接続ファイルを作成することが出来そうです。
set_wlan_country () (
if [ "$#" -ne 1 ]; then
usage set_wlan_country
exit 1
fi
# shellcheck disable=SC2030
COUNTRY="$1"
raspi-config nonint do_wifi_country "$COUNTRY"
)
set_wlan () (
HIDDEN="false"
PLAIN=0
for arg in "$@"; do
# shellcheck disable=SC2031
if [ "$arg" = "-h" ] || [ "$arg" = "--hidden" ]; then
HIDDEN="true"
elif [ "$arg" = "-p" ] || [ "$arg" = "--plain" ]; then
PLAIN=1
elif [ -z "${SSID+set}" ]; then
SSID="$arg"
elif [ -z "${PASS+set}" ]; then
PASS="$arg"
elif [ -z "${COUNTRY+set}" ]; then
COUNTRY="$arg"
else
usage set_wlan
exit 1
fi
done
if [ -z "${SSID+set}" ]; then
usage set_wlan
exit 1
fi
if [ -n "$COUNTRY" ]; then
set_wlan_country "$COUNTRY"
fi
CONNFILE=/etc/NetworkManager/system-connections/preconfigured.nmconnection
UUID=$(uuid -v4)
cat <<- EOF >${CONNFILE}
[connection]
id=preconfigured
uuid=${UUID}
type=wifi
[wifi]
mode=infrastructure
ssid=${SSID}
hidden=${HIDDEN}
[ipv4]
method=auto
[ipv6]
addr-gen-mode=default
method=auto
[proxy]
EOF
if [ ! -z "${PASS}" ]; then
cat <<- EOF >>${CONNFILE}
[wifi-security]
key-mgmt=wpa-psk
psk=${PASS}
EOF
fi
# NetworkManager will ignore nmconnection files with incorrect permissions,
# to prevent Wi-Fi credentials accidentally being world-readable.
chmod 600 ${CONNFILE}
)
[参考 (1)] 実際にインストール後に生成されたファイルを下記に示します。
※ ssid と psk は適当な値に修正しています。
[connection]
id=preconfigured
uuid=c9677410-652a-457f-abe2-0a3f7a1dd8af
type=wifi
[wifi]
mode=infrastructure
ssid=xxxxx-yyyyy
hidden=false
[ipv4]
method=auto
[ipv6]
addr-gen-mode=default
method=auto
[proxy]
[wifi-security]
key-mgmt=wpa-psk
psk=1234ec0f4cb652cc3873de1780a95ef8aec245c838e7ac61251c20b8ecb56789
[補足] NetworkManager のディレクトリ構成
/media/yukio/rootfs1/etc$ tree NetworkManager/ | grep -v dir | grep -v ^$
NetworkManager/
├── NetworkManager.conf
├── conf.d
├── dispatcher.d
│ ├── 01-ifupdown
│ ├── no-wait.d
│ ├── pre-down.d
│ └── pre-up.d
├── dnsmasq-shared.d
├── dnsmasq.d
└── system-connections # ★ このディレクトリに接続設定ファイル格納する
ルートファイルシステム上の system-connections ディレクトリ(★)に、固定IPアドレスを設定した有線ネットワーク接続設定ファイルをコピーしておくと OSインストール中に固定IPアドレスによるネットワーク接続が可能になります。
※ Ubuntu では ルートファイルシステムは読み書きモードになっているのでコピーされた設定ファイルはSDカードに保持されます。
2-3 (4) 一般: ロケール変更
rpi-imager の画面では「ロケールを設定する」となっていますが、カスタマイズ処理ではロケール自体は処理されません。OSインストール後に手動で実行する必要が有ります。
キーボード設定: [引数] "jp"
set_keymap () (
if [ "$#" -ne 1 ]; then
usage set_keymap
exit 1
fi
raspi-config nonint do_configure_keyboard "$1"
)
タイムゾーンゾーン設定: [引数] "Asia/Tokyo"
set_timezone () (
if [ "$#" -ne 1 ]; then
usage set_timezone
exit 1
fi
raspi-config nonint do_change_timezone "$1"
)
[参考] OSインストール終了後にSSHログインしてロケールを確認したところ
# Default: UK English
raspi@raspi-2w-dev:~ $ echo $LANG
en_GB.UTF-8
raspi@raspi-2w-dev:~ $ cat /etc/locale.gen | grep -v ^# | grep -v ^$
en_GB.UTF-8 UTF-8
2-3 (5) サービス: SSHの使用
- 引数に応じて
/etc/ssh/sshd_conf
の設定を変更 - SSH サービスを有効に設定
enable_ssh () (
ENABLE=1
KEY_ONLY_SED_STR='s/^[#\s]*PasswordAuthentication\s\+\S\+$/PasswordAuthentication no/'
PASSAUTH_SED_STR='s/^[#\s]*PasswordAuthentication\s\+\S\+$/PasswordAuthentication yes/'
for arg in "$@"; do
if [ "$arg" = "-k" ] || [ "$arg" = "--key-only" ]; then
sed -i "$KEY_ONLY_SED_STR" /etc/ssh/sshd_config
elif [ "$arg" = "-p" ] || [ "$arg" = "--pass-auth" ]; then
sed -i "$PASSAUTH_SED_STR" /etc/ssh/sshd_config
elif [ "$arg" = "-d" ] || [ "$arg" = "--disabled" ]; then
ENABLE=0
else
add_ssh_keys "$arg"
fi
done
if [ "$ENABLE" = 1 ]; then
systemctl -q enable ssh
fi
)
[補足] 公開鍵が指定された場合、下記のようにパスワード認証がで不可に設定されます。
/etc/ssh/ssh_config
raspi@raspi-2w-dev:~ $ cat /etc/ssh/sshd_config \
> | grep -v ^# | grep -v ^$ | grep Password
PasswordAuthentication no
OSのカスタマイズ機能が OSインストール時にどのように処理されているか、呼び出し先のスクリプトを見ることで理解できるようになりました。
特に WiFi接続処理ではどのディレクトリにどのような接続設定ファイルを設定するとWiFi接続が利用可能になるかも理解できました。
多くの処理が raspi-config CLI を呼び出すことによりカスタマイズ機能を実現しています。
3 raspi-config CLI の活用
最近の Raspberry Pi は性能が良くなったとはいえ、GUIによる操作は普段使いのパソコンのようにサクサクと快適に行えるものではありません。
今回検証に使用した Raspberry Pi Zero 2W では Rapberry Pi Configuration 画面を表示持するのに約8秒近くかかりました。
さすがに OSインストール時のみモニターを接続する必要が有りますが、Raspberry Pi をサーバー用途で使う場合、リモートから SSHでログインして保守作業を行なえるので普段はモニターもキーボードも端末に接続することはありません。
OSインストール完了直後に表示れさる画面には WiFi 接続の IPアドレスが数秒間トーストで表示されます。そのIPアドレスに SSHでログインすればあとはコマンドラインから固定IPアドレスに変更することも可能です。
※このスクリーンショットを取るためにキーボードは繋いでいます。
3-1 キャラクタベースの設定画面からの変更
開発用PCからディスクトップ画面に表示されたIPアドレスにSSHログインします。
管理者権限 (sudo) で raspi-config スクリプトを引数なしで実行するとテキストモード用のウィンドウが開きメニューを選択しながら各種設定変更が可能です。
raspi@raspi-2w-dev:~ $ sudo raspi-config
以下は最初に表示されるトップ画面です。
例えば I2C プロトコルを有効にするには、インターフェイスメニューを辿り I2C を選択
有効化確認画面で <Yes> を選択し、変更済み画面で <ok> を押下することになります。
ただしこの方法も変更する項目が多いと結構ストレスの溜る作業になります。
3-2 raspi-config CLI で変更する
これ以降の中級者以上向けの内容となります。
初心者の方は失敗しても良いようにOSインストール後にシャットダウンし、SDカードをパソコンにバックアップしてから実行してください。
公式ドキュメント Configuration non-interactive raspi-config
コマンド実行オブションとして nonint (non-interactive) を最初に指定します。
$ sudo raspi-config nonint [optional-argument]
先の I2Cの例だと raspi-config CLIを使うとたった1行で済んでしまいます。。
raspi@raspi-2w-dev:~ $ sudo raspi-config nonint do_i2c 0
# 設定値の確認 ※0: 有効
raspi@raspi-2w-dev:/boot $ raspi-config nonint get_i2c
0
以降の設定は Raspberry Pi をサーバーとして利用する場合の最低限の設定になります。
3-2-1 ロケールを日本語に変更する
もし Raspberry Pi を日本語を表示するようなスクリプトを実行するには(例えば matplotlib 等) ロケールを日本語に変える必要があります。項目 [ 2-3 (4) ] で簡単に説明しましたがカスタマイズしてもロケールはデフォルトのままです。
# OSインストール直後
raspi@raspi-2w-dev:~ $ echo $LANG
en_GB.UTF-8
最近の Raspberr Pi OS (Debian) でサポートしている日本語ロケールは2つしかありません。
※ただし 2行目の EUC-JP は使うことは無いでしょう。
raspi@raspi-2w-dev:~ $ cat /usr/share/i18n/SUPPORTED | grep ja
ja_JP.UTF-8 UTF-8
ja_JP.EUC-JP EUC-JP
値はスペース区切りで下記のように2つ設定します。
do_change_locale ja_JP.UTF-8 UTF-8
raspi@raspi-2w-dev:~ $ sudo raspi-config nonint do_change_locale ja_JP.UTF-8 UTF-8
Generating locales (this might take a while)...
ja_JP.UTF-8... done
Generation complete.
raspi@raspi-2w-dev:~ $ sudo reboot
Broadcast message from root@raspi-2w-dev on pts/1 (Mon 2024-12-23 16:53:04 JST):
The system will reboot now!
リブート後に変更が反映されます。
raspi@raspi-2w-dev:~ $ localectl status
System Locale: LANG=ja_JP.UTF-8
VC Keymap: (unset)
X11 Layout: jp
X11 Model: pc105
3-2-2 ブートモードをコンソールログインに変更
コンソール起動、ログインが必要 (B1) に変更します。
do_boot_behavior B1
# OSインストール直後は GUI
raspi@raspi-2w-dev:~ $ systemctl get-default
graphical.target
# コンソール起動、ログインが必要 (B1) に変更
raspi@raspi-2w-dev:~ $ sudo raspi-config nonint do_boot_behaviour B1
# コンソール起動に変更されます
raspi@raspi-2w-dev:~ $ systemctl get-default
multi-user.target
リブート後に画面はコンソール画面に切り替わりログイン待受けとなりますが、待受状態でもサービスは稼働しています。
3-2-3 インターフェイスを有効する
I2C と SPI、シリアルポート (UART) を有効にしておけば当面は問題ないでしょう。
初期設定を確認します。値が1なら利用不可です。
raspi@raspi-2w-dev:~ $ raspi-config nonint get_i2c
1
raspi@raspi-2w-dev:~ $ raspi-config nonint get_spi
1
raspi@raspi-2w-dev:~ $ raspi-config nonint get_serial_hw
1
それぞれ有効に設定する
raspi@raspi-2w-dev:~ $ sudo raspi-config nonint do_i2c 0
raspi@raspi-2w-dev:~ $ sudo raspi-config nonint do_spi 0
raspi@raspi-2w-dev:~ $ sudo raspi-config nonint do_serial_hw 0
それぞれ変更結果を確認する
raspi@raspi-2w-dev:~ $ raspi-config nonint get_i2c
0
raspi@raspi-2w-dev:~ $ raspi-config nonint get_spi
0
raspi@raspi-2w-dev:~ $ raspi-config nonint get_serial_hw
0
変更した項目は /boot/firmware/config.txt に反映されます。
※変更前にファイルをコピー (config_org.txt) し、設定後に diffで差分を確認
※先頭: '+' のものが反映された行の値、'-'のものはコメントアウトされた行
$ diff --unified config_org.txt config.txt
*****************************************************************************************
--- config_org.txt 2024-12-22 15:31:18.063320145 +0900
+++ config.txt 2024-12-22 15:31:51.571455916 +0900
@@ -3,9 +3,9 @@
# Some settings may impact device functionality. See link above for details
# Uncomment some or all of these to enable the optional hardware interfaces
-#dtparam=i2c_arm=on
+dtparam=i2c_arm=on
#dtparam=i2s=on
-#dtparam=spi=on
+dtparam=spi=on
# Enable audio (loads snd_bcm2835)
dtparam=audio=on
@@ -46,4 +46,5 @@
dtoverlay=dwc2,dr_mode=host
[all]
+enable_uart=1
最後に
raspi-config はバイナリではなく普通のシェルスクリプトで作られています。
raspi@raspi-2w-dev:~ $ which raspi-config
/usr/bin/raspi-config
raspi@raspi-2w-dev:~ $ LANG=C;ls -l /usr/bin/raspi-config --time-style long-iso \
| grep -v total
-rwxr-xr-x 1 root root 120254 2024-12-10 20:47 /usr/bin/raspi-config
ローカルの PC にコピーしてソースを見れば、実行するコマンドと必要なパラメータが確認できます。さらにはシェルスクリプトの勉強にもなるので一度ご覧になってみてください。
※くれぐれも端末上のvimで直接スクリプトを見ないように。
以下は開発用PCのディスクトップにコピーしたもの。
$ scp raspi@192.168.0.23:/usr/bin/raspi-config ~/Desktop
raspi-config 100% 117KB 8.0MB/s 00:00
ちなみにロケール変更は以下の関数です。
do_change_locale() {
if [ "$INTERACTIVE" = True ]; then
dpkg-reconfigure locales
else
if ! LOCALE_LINE="$(grep -E "^$1( |$)" /usr/share/i18n/SUPPORTED)"; then
return 1
fi
export LC_ALL=C
export LANG=C
LG="/etc/locale.gen"
NEW_LANG="$(echo $LOCALE_LINE | cut -f1 -d " ")"
[ -L "$LG" ] && [ "$(readlink $LG)" = "/usr/share/i18n/SUPPORTED" ] && rm -f "$LG"
echo "$LOCALE_LINE" > /etc/locale.gen
update-locale --no-checks LANG
update-locale --no-checks "LANG=$NEW_LANG"
dpkg-reconfigure -f noninteractive locales
fi
}
こちらの画面は開発用PCで dpkg-reconfigure locales
実行したもの。
$ sudo dpkg-reconfigure locales
次回は、今回紹介した imager_custom スクリプトの WiFi接続処理を参考に、NetworkManager用に固定IPアドレスを設定した有線接続設定ファイルとWiFi接続設定ファイルを生成するシェルスクリプトを紹介する予定です。