刹那(せつな)の瞬き

Willkömmen! Ich heiße Setsuna. Haben Sie etwas Zeit für mich?

KDE Plasma 5で日本語キーボードからドイツ語の文字やユーロ通貨記号を入力する

KDE Plasma 5 で日本語キーボードからドイツ語のウムラウトエスツェットを入力したい場合、Compose Key を設定するとキーストロークの組み合わせで特殊文字を入力できます。

後述する内容は KDE neon 5.20 と Kubuntu 20.10 で確認しました。

1. Compose Key を設定する

Comopse Key は初期状態では無効になっているので、まずは有効にします。

KDE システム設定を起動 ->「入力デバイス」->「キーボード」->「詳細」タブを選択し、「キーボードオプションを設定」をチェックします。

f:id:infinity_volts:20210120155454p:plain

ツリー表示の「Position of Compose Key」を展開 ->「Right Alt」にチェックをつけて ->「適用」ボタンをクリックすると、右AltキーがComposeキーになります。

設定はすぐに反映されるので、再ログイン等は不要です。

2. 特殊文字の入力

特殊文字は2段階入力になります。

例えば ä を入力するなら、最初にComposeShift"(フルキーの2)を同時に押して、一旦離してからAキーを押すと ä になります。

入力するキーの組み合わせ
文字 キーストローク1 キーストローク2
ä Compose+Shift+" A
Ä Compose+Shift+" Shift+A
ö Compose+Shift+" O
Ö Compose+Shift+" Shift+O
ü Compose+Shift+" U
Ü Compose+Shift+" Shift+U
ß Compose+S Compose+S
Compose+Shift+S Compose+Shift+S
Compose+Shift+= EまたはC

エスツェットの入力は少し違ってて、ComposeキーやShiftキーは押下したままでSを 2 度打鍵します。大文字にも対応してて嬉しいです。

3. おまけ

詳細はこちらのサイトが参考になります。

ついでに Unicode のコードポイントも貼っておきます。

コードポイント
文字 Unicode 文字 Unicode 文字 Unicode
ä U+00E4 ö U+00F6 ü U+00FC
Ä U+00C4 Ö U+00D6 Ü U+00DC
ß U+00DF U+1E9E U+20AC

 

なぜ必要だったのか

年に数回程度ですが、ネット検索でドイツ語の単語を入力する事があります。

ウムラウトエスツェットを含む単語は、特殊文字を使わなくても組み合わせで代用できるのは承知してるのですが、若干検索結果が変化します。

例えば Google 検索でオオカミを検索する場合、wölfe で約 24,400,000 件、woelfe で約 7,180,000 件と、結果と件数が随分違ってます。
なので、検索するキーワードは単語をそのまま入力したいのです。

ぼやき、というか困ってる事

Mac なら特に設定変更しなくてもoptionキーとの組み合わせで Umlaut や Eszett を扱えるので、今でもドイツ語を扱うなら基本的に Mac を使ってます。

しかし、Mac を立ち上げてない場合は別の PC で検索するのですが、これが Ubuntu だと入力できなくて困ってます。

Ubuntu 18.04 以降、GNOME Tweaks で Compose Key の設定をしたつもりでも有効にならず、2段階入力が失敗します。
Compose Key の設定値はgsettings get org.gnome.desktop.input-sources xkb-optionsで確認すると反映されているのですが、期待通りに動作しません。
/etc/dconf/ あたりの情報を漁っても解決できてません。

幸い Unicode のコードポイントを入力する方法なら可能ですが、ちょっと不便です。
いちいちコードを調べるならコード表から文字をコピペした方が楽ですし。

Ubuntu 20.10 になった現在でも正しい設定方法は不明です。
Ubuntu というか GNOME 利用者はどうしてるんだろう。

一方で、KDE neon / Kubuntu なら設定は必要だけど、割とすんなり扱えたので、とりあえずは満足しました。やっぱり KDE Plasma 5 は快適ですわ。

Nanaのthreads::poolを利用してnanodbcの実行結果を表示する

Linux 環境でも ODBC 接続をスレッド内で利用可能なのは確認できました。

もう一歩進めるとスレッドプールやワーカースレッドの話が出てきますが、どうせならGUI を絡めてみたくなりました。

ウィンドウを表示して、そこに結果セットを表示したくなるのは自然だと思います。
今回は GUI framework に Nana C++ Library を利用してみました。

実行結果とソースコード

2 つのクエリを実行し、結果を表示するサンプルです。

開始ボタンをクリックすると、フォームに表示される2つの nana::listbox にそれぞれのクエリの実行結果を表示します。

f:id:infinity_volts:20201206155350g:plain

・main.cpp

nana::listbox に表示させたい処理をラムダ式で記述しておいて、それをスレッドプール(nana::threads::pool)に登録しつつ、開始ボタンのクリックイベントに割り当ててます。

#include <nana/gui.hpp>
#include <nana/gui/widgets/label.hpp>
#include <nana/gui/widgets/listbox.hpp>
#include <nana/gui/widgets/button.hpp>
#include <nana/threads/pool.hpp>
#include <nana/system/platform.hpp>
#include <nanodbc/nanodbc.h>

int main()
{
    std::locale::global(std::locale(""));
    std::string conn_str = "Driver={ODBC Driver 17 for SQL Server};Server=localhost;UID=sa;PWD=abcd1234$;Database=my_test_db;";

    nana::threads::pool th_pool;

    nana::form fm;
    fm.caption("Nana - nanodbc");
    fm.size(nana::size{ 450, 400 });
    
    nana::label lbl1{ fm, "SQLServer接続テスト  <bold blue size=12>MS版ODBCドライバ</>" };
    lbl1.format(true);

    nana::listbox list1{ fm };
    list1.append_header("コード");
    list1.append_header("氏名");
    list1.append_header("入社日");
    list1.show_header(true);
    list1.auto_draw(true);

    auto th1 = [ &conn_str, &list1 ] {
        list1.clear();
        nanodbc::connection conn(conn_str);
        nanodbc::string sql_text(NANODBC_TEXT("SELECT コード,氏名,入社日 FROM 社員 WHERE コード<300 ORDER BY コード"));
        nanodbc::result rs = nanodbc::execute(conn, sql_text);
        for (const auto& row : rs) {
            auto cat = list1.at(0);
            auto val_int = row.get<nanodbc::string>("コード");
            auto val_str = row.get<nanodbc::string>("氏名");
            auto val_date = row.get<nanodbc::string>("入社日");
            cat.append(std::initializer_list<nanodbc::string>{ val_int, val_str, val_date });
            nana::system::sleep(100);  // 0.1 sec
        }
    };

    nana::listbox list2{ fm };
    list2.append_header("コード");
    list2.append_header("氏名");
    list2.append_header("入社日");
    list2.show_header(true);
    list2.auto_draw(true);

    auto th2 = [ &conn_str, &list2 ] {
        list2.clear();
        nanodbc::connection conn(conn_str);
        nanodbc::string sql_text(NANODBC_TEXT("SELECT コード,氏名,入社日 FROM 社員 WHERE コード>199 ORDER BY 入社日"));
        nanodbc::result rs = nanodbc::execute(conn, sql_text);
        for (const auto& row : rs) {
            auto cat = list2.at(0);
            auto val_int = row.get<nanodbc::string>("コード");
            auto val_str = row.get<nanodbc::string>("氏名");
            auto val_date = row.get<nanodbc::string>("入社日");
            cat.push_back(val_int);
            cat.back().text(1, val_str);
            cat.back().text(2, val_date);	
            nana::system::sleep(100);  // 0.1 sec
        }
    };

    nana::button btn_start{ fm, "開始" };
    btn_start.events().click(nana::threads::pool_push(th_pool, th1));
    btn_start.events().click(nana::threads::pool_push(th_pool, th2));

    nana::button btn_close{ fm, "閉じる" };
    btn_close.events().click([ &fm ] {
        fm.close();
    });

    nana::place fm_place{ fm };
    fm_place.div("<><weight=90% vertical<><weight=95% vertical<weight=25 text><weight=5><vertical listboxes gap=5><weight=5><weight=25 <>< weight=40% buttons gap=20><>> ><> ><>");
    fm_place["text"] << lbl1;
    fm_place["listboxes"] << list1 << list2;
    fm_place["buttons"] << btn_start << btn_close;
    fm_place.collocate();
	
    fm.show();
    nana::exec();
}

少ないコーディング量でフォーム表示までたどり着けるのは良いですね。
フォームのウィジェットはベタに書いてから整形してますが、他にも方法があります。

データベース接続失敗やクエリ失敗時の例外処理、クリック連打対策等、まだ実装してない部分もありますが、とりあえずの目的は達成できました。

・CMakeLists.txt
cmake_minimum_required(VERSION 3.12)
project(gui_odbc CXX)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
find_package(Threads REQUIRED)
find_package(nanodbc REQUIRED)
add_executable(gui_odbc main.cpp)
target_link_libraries(gui_odbc PRIVATE Threads::Threads)
target_link_libraries(gui_odbc PRIVATE nana X11 Xft fontconfig)
target_link_libraries(gui_odbc PRIVATE nanodbc)

雑記

いつもなら Qt5 でコーディングするようなネタですが、今回は QODBC ではなくnanodbc を使ってるので、Qt5 である必要はない。それなら wxWidgets でも...と思いましたが、折角の機会なので、初めての Nana C++ Library に挑戦してみました。

これを選んた理由はいくつかありますが、 GUI プログラミングでありがちな「処理が busy 状態だと描画を妨げる」件について、ドキュメントを見つけたのが大きいかも。

ここに Nana の UI thread と nana::threads::pool について言及されてたので、それを参考にして、コードを書いてみた次第です。

std::threadを利用してnanodbcからクエリを実行する

現在 Linux 環境の ODBC 接続では SQL_ATTR_ASYNC_ENABLE に SQL_ASYNC_ENABLE_ON を設定しても機能しません。※iODBC や商用ドライバは調べてません。
そして nanodbc の async_ 系関数も Linux 環境では実装されてません。
WaitForSingleObject()とか無いもんね。残念です。

その一方で、 Linux 環境の ODBC ドライバでも別スレッドを立ち上げれば SQL 文を並行して実行可能との事。ODBC ドライバ側で直列化されるとしても、です。

非同期実行等がダメでも、それはそれ。
スレッドを立てて全体の処理時間を効率良く短縮できるなら...と、引き続き nanodbc で試してみました。

ソースコード

とりあえずスレッドを 2 つ用意して、クエリを実行してみます。

・main.cpp
#include <iostream>
#include <future>
#include <chrono>
#include <nanodbc/nanodbc.h>

int main()
{
    std::locale::global(std::locale(""));
    std::string conn_str = "Driver={ODBC Driver 17 for SQL Server};Server=localhost;UID=sa;PWD=abcd1234$;Database=my_test_db;";
    auto start = std::chrono::system_clock::now();
    try
    {
        std::cout << "-- 処理開始" << std::endl;
        // thread #1
        auto th1 = std::thread([&conn_str] {
            std::cout << "-- thread #1" << std::endl;
            //std::this_thread::sleep_for(std::chrono::milliseconds(800));
            nanodbc::connection conn(conn_str);
            nanodbc::string sql_text(NANODBC_TEXT("SELECT コード,氏名,入社日 FROM 社員 WHERE コード>199 ORDER BY コード DESC"));
            nanodbc::result rs = nanodbc::execute(conn, sql_text);
            for (const auto& row : rs) {
                auto val_int = row.get<int>("コード");
                auto val_str = row.get<nanodbc::string>("氏名");
                auto val_date = row.get<nanodbc::string>("入社日");
                std::cout << "th#1 " << val_int << " | " << val_str << " | " << val_date << std::endl;
            }
        });
        // thread #2
        auto th2 = std::thread([&conn_str] {
            std::cout << "-- thread #2" << std::endl;
            //std::this_thread::sleep_for(std::chrono::milliseconds(500));
            nanodbc::connection conn(conn_str);
            nanodbc::string sql_text(NANODBC_TEXT("SELECT コード,氏名,入社日 FROM 社員 WHERE コード>199 ORDER BY 入社日 DESC"));
            nanodbc::result rs = nanodbc::execute(conn, sql_text);
            for (const auto& row : rs) {
                auto val_int = row.get<int>("コード");
                auto val_str = row.get<nanodbc::string>("氏名");
                auto val_date = row.get<nanodbc::string>("入社日");
                std::cout << "th#2 " << val_int << " | " << val_str << " | " << val_date << std::endl;
            }
        });
        std::cout << "-- 途中で何かの処理開始" << std::endl;
        std::cout << "-- 処理中 (1秒くらい)" << std::endl;
        std::this_thread::sleep_for(std::chrono::seconds(1));
        std::cout << "-- 途中で何かの処理終了" << std::endl;
        th1.join();
        th2.join();
        std::cout << "-- 処理終了" << std::endl;
    }
    catch (const std::exception& e)
    {
        std::cerr << e.what() << std::endl;
        return EXIT_FAILURE;
    }
    auto end = std::chrono::system_clock::now();
    std::cout << "経過時間(ミリ秒):"
        << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count()
        << std::endl;
    return EXIT_SUCCESS;
}

std::thread に渡すラムダ式でキャプチャしているのは接続文字列です。
nanodbc::connection はスレッド内で生成する必要があります。

・CMakeLists.txt
cmake_minimum_required(VERSION 3.0)
project(odbc_thread CXX)
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
find_package(nanodbc REQUIRED)
add_executable(odbc_thread main.cpp)
target_link_libraries(odbc_thread PRIVATE pthread nanodbc)

実行結果

-- 処理開始
-- thread #1
-- 途中で何かの処理開始
-- 処理中 (1秒くらい)
-- thread #2
th#1 th#2 307207 |  | 松沢 誠一小川 さよ子 |  | 1994-04-011987-04-01

th#2 210 | 成宮 真紀 | 1991-04-01
th#1 305 | 青木 俊之 | 1988-04-01
th#2 204 | 川村 匡 | 1990-04-01
th#1 304 | 山本 雅治 | 1989-04-01
th#2 304 | 山本 雅治 | 1989-04-01
th#1 210 | 成宮 真紀 | 1991-04-01
th#2 305 | 青木 俊之 | 1988-04-01
th#1 207 | 松沢 誠一 | 1994-04-01
th#2 307 | 小川 さよ子 | 1987-04-01
th#1 204 | 川村 匡 | 1990-04-01
-- 途中で何かの処理終了
-- 処理終了
経過時間(ミリ秒):1000

拍子抜けするくらいあっさりと意図した結果になりました。
スレッドを待機させても大丈夫でした。

この後、ソースを書き換えて、std::vector<std::thread>みたいなコンテナを用意して、1000個くらいpush_back(std::thread(…等としてみましたが問題ありませんでした。

スレッド生成と接続生成、両方のコストを加味してもなかなか良い感じです。

Ubuntu20.10でnanodbcからODBCの対応状況を確認する

Ubuntu というか Linux 環境で RDBMS 、特に SQL ServerODBC 接続していると、ついつい Windows 環境と同等な動作を期待してしまいます。

そもそも前提が異なるので完全互換は期待してません。
それでも、どの程度対応してるのかな?と思い立ったので、C++ ライブラリの nanodbc を利用して確認してみました。

環境

  • OS: Ubuntu 20.10
  • g++ (Ubuntu 10.2.0-13ubuntu1) 10.2.0
  • nanodbc v2.13.0
  • unixODBC 2.3.7

ODBC ドライバ

私の手元にある ODBC ドライバについて調査してみました。

ドライバ SQL_DRIVER_NAME SQL_DRIVER_VER パッケージ
msodbc libmsodbcsql-17.6.so.1.1 17.06.0001 公式サイト
freetds libtdsodbc.so 01.02.0003 tdsodbc
mysql libmyodbc8w.so 08.00.0022 公式サイト
maria libmaodbc.so 03.01.0009 odbc-mariadb
pg psqlodbcw.so 12.02.0000 odbc-postgresql

※表現の都合上、勝手にドライバに略名をつけてます。

調査結果

各ドライバの調査結果の一部を載せておきます。

パラメータ (sqlext.h) msodbc freetds mysql maria pg
SQL_DRIVER_ODBC_VER 03.52 03.50 03.80 03.51 03.51
SQL_ASYNC_MODE 2 0 0 0 0
SQL_ACTIVE_CONNECTIONS 0 0 0 0 0
SQL_ACTIVE_STATEMENTS 1 1 0 0 0
SQL_ODBC_API_CONFORMANCE 2 2 1 1 1
SQL_ODBC_SQL_CONFORMANCE 1 1 1 1 1
SQL_MULT_RESULT_SETS Y Y Y Y Y
SQL_ACTIVE_ENVIRONMENTS 0 0 0 0 0
SQL_SQL_CONFORMANCE 1 1 4 4 1
SQL_MAX_ASYNC_CONCURRENT _STATEMENTS 1 1 0 0 core dump
SQL_ODBC_INTERFACE
_CONFORMANCE
3 2 2 1 1
SQL_ATTR_ODBC_VERSION 380 380 380 380 380
SQL_ATTR_AUTOCOMMIT 1 1 1 4 1

unixODBC の SQL_ODBC_VER は 03.52 です。
SQL_ATTR_ODBC_VERSION が 3 ではなく 380 なのは、nanodbc の設定です。

残念ながら ODBC 3.8 の Driver-Aware Connection Pooling や 非同期通知等は使えないようです。

ソースコード

nanodbc::connection の get_info<T>() を利用すると手軽に情報を取得できます。

get_info<T>() は ODBC API の SQLGetInfo() を呼び出してます。
環境属性や接続属性を調査する場合は、ハンドルが用意されているので、

  • SQLGetEnvAttr() には native_env_handle()
  • SQLGetConnectAttr() には native_dbc_handle()

を指定すると情報を取得できます。

以下は、冗長な部分を省いたコードのサンプルです。

・ソースファイル (main.cpp)

#include <iostream>
#include <sql.h>
#include <sqlext.h>
#include <nanodbc/nanodbc.h>

int main() {
    std::locale::global(std::locale(""));
    std::string conn_str = "Driver={ODBC Driver 17 for SQL Server};Server=localhost;UID=sa;PWD=abcd1234$;Database=my_test_db;";
    //std::string conn_str = "Driver={FreeTDS};ServerName=mssql-server;UID=sa;PWD=abcd1234$;Database=my_test_db;";
    //std::string conn_str = "Driver={MySQL ODBC 8.0 Driver};Server=localhost;UID=dareka;PWD=dareda;Database=my_test_db;";
    //std::string conn_str = "Driver={MariaDB Unicode};Server=localhost;UID=dareka;PWD=dareda;Database=my_test_db;";
    //std::string conn_str = "Driver={PostgreSQL Unicode};Server=localhost;UID=dareka;PWD=dareda;Database=my_test_db;";
    try
    {
        nanodbc::connection conn(conn_str);
        std::cout << "get_info()" << std::endl;
        {
            auto ret_ver = conn.get_info<std::string>(SQL_DRIVER_ODBC_VER);
            std::cout << "-- get_info(SQL_DRIVER_ODBC_VER) --> " << ret_ver << std::endl;
            auto ret_am = conn.get_info<SQLUINTEGER>(SQL_ASYNC_MODE);
            std::cout << "-- get_info(SQL_ASYNC_MODE) --> " << ret_am  << std::endl;
        }
        std::cout << "SQLGetEnvAttr()" << std::endl;
        {
            SQLINTEGER val = 0;
            SQLRETURN ret = SQLGetEnvAttr(conn.native_env_handle(), SQL_ATTR_ODBC_VERSION, &val, sizeof(val), nullptr);
            std::cout << "-- SQL_ATTR_ODBC_VERSION : ret = " << ret << " / val = "  << val  << std::endl;
        }
        std::cout << "SQLGetConnectAttr()" << std::endl;
        {
            SQLINTEGER val = 0;
            SQLRETURN ret = SQLGetConnectAttr(conn.native_dbc_handle(), SQL_ATTR_ASYNC_ENABLE, &val, sizeof(val), nullptr);
            std::cout << "-- SQL_ATTR_ASYNC_ENABLE : ret = " << ret << " / val = "  << val  << std::endl;
        }
    }
    catch (const std::exception& e)
    {
        std::cerr << e.what() << std::endl;
        return EXIT_FAILURE;
    }
    return EXIT_SUCCESS;
}

・CMakeLists.txt

cmake_minimum_required(VERSION 3.0)
project(odbc_getinfo CXX)
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
find_package(nanodbc REQUIRED)
add_executable(odbc_getinfo main.cpp)
target_link_libraries(odbc_getinfo PRIVATE pthread nanodbc)

所感 

当初、昔を思い出しながら SQLAllocHandle() で環境ハンドル用意して、SQLSetEnvAttr() で ODBC バージョン指定して、SQLAllocHandle() で接続ハンドル用意して...と、C で簡単なプログラムを書いて環境を調べました。
とりあえず目的は達成できたのですが、煩雑すぎて不満が募ります。

そこで、以前調査した nanodbc を使ってみたのですが、やっぱりお手軽です。
Poco や Qt5 より軽量と言うか薄い分、Win32API っぽいコーディングはやりやすいかも。

Ubuntu20.10でMarble Mouseの設定方法が変わってた

Ubuntu 20.10 がリリースされたので、早々に OS をアップグレードしました。

今回はクリーンインストールではなく、久しぶりのアップグレードです。
事前に躓きそうなパッケージを remove しておいたので割とスムーズに完了しました。

リポジトリを調整して、各種パッケージの環境を整えて作業完了。
さて、いつもの作業に戻ろうか...

なんて思ってたら Marble Mouse のスクロール機能が有効になってません!
ターミナルから確認しても、

$ echo $XDG_SESSION_TYPE
x11
$ xinput list
⎡ Virtual core pointer                    	id=2	[master pointer  (3)]
⎜   ↳ Virtual core XTEST pointer              	id=4	[slave  pointer  (2)]
⎜   ↳ Logitech USB Trackball                  	id=8	[slave  pointer  (2)]
 〜 (ざっくり省略) 〜

セッションは Xorg のままだし、xinput からも見えてます。

Ubuntu 20.04 LTS では、上記のサイトに従い libinput 用の構成ファイルを /usr/share/X11/xorg.conf.d/ に配置してましたが、それも消えずに残ってました。

....

このままでは困るので、ダメ元で Wayland での設定方法を試してみました。

$ gsettings set org.gnome.desktop.peripherals.trackball scroll-wheel-emulation-button 9

バッチリです!即時反映されるので、すぐにスクロール機能が有効になりました。

今までは Xorg と Wayland で設定方法が異なり、少々煩わしかったのですが、gsettings に統一されて良かったです。

....

GNOME 3.38 ベースになって、色々と細かいところが改善されてますね。

ちなみに Kubuntu 20.10 で確認したところ、こちらの設定方法は今まで通りでした。

/boot/efiにbootフラグが付かなかったので

KDE neon をインストールした際、パーティションを手動で作成しました。

OS インストール後は普通に使用してたのですが、Dolphin を起動するとデバイス欄に覚えのないパーティションが表示されました。

確認したところ、それは EFI パーティションだったのですが、通常の FAT32 パーティションとして扱われてました。

EFI パーティションの作成では、

  • サイズ: 512MB
  • フォーマット: FAT32
  • マウントポイント /boot/efi
  • boot フラグ指定

を設定したつもりですが、boot フラグが反映されなかったみたいです。

OS をインストールしたデバイス/dev/sdbなので、sudo sfdisk -l /dev/sdbで確認しても、"EFI システム" とは表示されません。

仕方ないので、parted で確認しながら修正してみました。

$ sudo parted /dev/sdb
GNU Parted 3.3
/dev/sdb を使用
GNU Parted へようこそ! コマンド一覧を見るには 'help' と入力してください。
(parted) print                                                            
モデル: ATA WDC WDS500G2B0A (scsi)
ディスク /dev/sdb: 500GB
セクタサイズ (論理/物理): 512B/512B
パーティションテーブル: gpt
ディスクフラグ: 

番号  開始    終了   サイズ  ファイルシステム  名前  フラグ
 1    1049kB  538MB  537MB   fat32                   msftdata
 2    538MB   483GB  482GB   ext4
 3    483GB   500GB  17.2GB  linux-swap(v1)          swap

(parted) 

print コマンドで確認すると、パーティション 1 のフラグが boot, esp になってません。
そしてパーティションラベルも空欄のままです。
ここは Ubuntu に合わせておきたいところです。

引き続き、parted の set コマンドと name コマンドを実行します。

(parted) set 1 boot on                                                    
(parted) name 1 "EFI System Partition"                                    
(parted) print                                                            
モデル: ATA WDC WDS500G2B0A (scsi)
ディスク /dev/sdb: 500GB
セクタサイズ (論理/物理): 512B/512B
パーティションテーブル: gpt
ディスクフラグ: 

番号  開始    終了   サイズ  ファイルシステム  名前                  フラグ
 1    1049kB  538MB  537MB   fat32             EFI System Partition  boot, esp
 2    538MB   483GB  482GB   ext4
 3    483GB   500GB  17.2GB  linux-swap(v1)                          swap

(parted) quit                                                             
通知: 必要であれば /etc/fstab を更新するのを忘れないようにしてください。

$

設定値が反映されているか sfdisk で確認すると、

$ sudo sfdisk -l /dev/sdb
ディスク /dev/sdb: 465.78 GiB, 500107862016 バイト, 976773168 セクタ
Disk model: WDC  WDS500G2B0A
単位: セクタ (1 * 512 = 512 バイト)
セクタサイズ (論理 / 物理): 512 バイト / 512 バイト
I/O サイズ (最小 / 推奨): 512 バイト / 512 バイト
ディスクラベルのタイプ: gpt
ディスク識別子: 2066E652-4BDC-C345-9EEB-489713F920D5

デバイス    開始位置  最後から    セクタ サイズ タイプ
/dev/sdb1       2048   1050623   1048576   512M EFI システム
/dev/sdb2    1050624 943130623 942080000 449.2G Linux ファイルシステム
/dev/sdb3  943130624 976768031  33637408    16G Linux スワップ

どうやら期待通りに設定できたようです。
Dolphin を再起動したところ、デバイス欄に表示されなくなりました。

....

Calamares Installer になってからも、以前 KDE neon をインストールした際は、普通に EFI パーティションを作成できてたはずなのに、何が問題だったんだろう。

前述の設定手順。
もしかして、設定順が影響してるのかな?だとすると、

ここに書いてあるように、フォーマットする前に boot フラグを指定する必要があるなら、私が指定した順番が誤ってたのかも。
またインストールする機会があれば注意してみよう。

Ryzen5 2600X / B450でsensorsの出力結果が思ってたのと違う

少し前に、Kernel 5.7 で Thermal Pressure が導入されてた事を知り、直接は関係ないのですが、私の PC でも温度センサを確認してみたくなりました。

今まで PC の温度センサについては無頓着だったので、これを機に調べてみました。
そしたら、思ってたより根が深かったので、備忘録として残しておきます。

....

現在、私が Ubuntu 20.04 LTS で使用しているハード構成は、

ですが、sudo apt install linux-generic-hwe-20.04-edgeを実行済みなので、

$ uname -r
5.8.0-25-generic

カーネルは kernel 5.8 系になってます。
※追記: 後述する内容は kernel 5.4 系のままでも同様でした。

....

まずは lm-sensors を導入します。

$ sudo apt install lm-sensors

すぐに sensors を実行するとこんな感じです。

$ sensors
k10temp-pci-00c3
Adapter: PCI adapter
Vcore:       788.00 mV 
Vsoc:        925.00 mV 
Tctl:         +26.8°C  
Tdie:         +26.8°C  
Icore:         4.00 A  
Isoc:          6.25 A  

iwlwifi_1-virtual-0
Adapter: Virtual device
temp1:            N/A  

思ってたのと随分違ってます。CPU コアの温度が出力されてません。

◆ とりあえず調べてみる

$ sudo sensors-detect --auto
# sensors-detect version 3.6.0
# System: Gigabyte Technology Co., Ltd. B450 AORUS PRO WIFI [Default string]
# Board: Gigabyte Technology Co., Ltd. B450 AORUS PRO WIFI-CF
# Kernel: 5.8.0-25-generic x86_64
# Processor: AMD Ryzen 5 2600X Six-Core Processor (23/8/2)
 〜(ざっくり省略)〜

Now follows a summary of the probes I have just done.

Driver `k10temp' (autoloaded):
  * Chip `AMD Family 17h thermal sensors' (confidence: 9)

Driver `to-be-written':
  * ISA bus, address 0xa40
    Chip `ITE IT8686E Super IO Sensors' (confidence: 9)

Driver `it87':
  * ISA bus, address 0xa60
    Chip `ITE IT8792E Super IO Sensors' (confidence: 9)

Note: there is no driver for ITE IT8686E Super IO Sensors yet.
Check https://hwmon.wiki.kernel.org/device_support_status for updates.

To load everything that is needed, add this to /etc/modules:
#----cut here----
# Chip drivers
it87
#----cut here----
If you have some drivers built into your kernel, the list above will
contain too many modules. Skip the appropriate ones!

Do you want to add these lines automatically to /etc/modules? (yes/NO)

Unloading cpuid... OK

出力結果を鑑みるに、まずは it87 モジュールを入れれば良さそうです。

ITE IT8686Eや /etc/modues に it87 を追記するのは後回し。
その前に it87 モジュールをロードして、sensors を実行してみます。

$ sudo modprobe it87
$ sensors
it8792-isa-0a60
Adapter: ISA adapter
in0:         774.00 mV (min =  +0.00 V, max =  +2.78 V)
in1:           1.08 V  (min =  +0.00 V, max =  +2.78 V)
in2:           1.12 V  (min =  +0.00 V, max =  +2.78 V)
+3.3V:         1.68 V  (min =  +0.00 V, max =  +2.78 V)
in4:           1.30 V  (min =  +0.00 V, max =  +2.78 V)
in5:           1.17 V  (min =  +0.00 V, max =  +2.78 V)
in6:           2.78 V  (min =  +0.00 V, max =  +2.78 V)  ALARM
3VSB:          1.67 V  (min =  +0.00 V, max =  +2.78 V)
Vbat:          1.69 V  
fan1:           0 RPM  (min =    0 RPM)
fan2:           0 RPM  (min =    0 RPM)
fan3:           0 RPM  (min =    0 RPM)
temp1:        +28.0°C  (low  = +127.0°C, high = +127.0°C)  sensor = thermistor
temp2:        +33.0°C  (low  = +127.0°C, high = +127.0°C)  sensor = thermistor
temp3:        +34.0°C  (low  = +127.0°C, high = +127.0°C)  sensor = thermistor
intrusion0:  ALARM

k10temp-pci-00c3
Adapter: PCI adapter
Vcore:       788.00 mV 
Vsoc:        931.00 mV 
Tctl:         +27.0°C  
Tdie:         +27.0°C  
Icore:         7.00 A  
Isoc:          6.00 A  

iwlwifi_1-virtual-0
Adapter: Virtual device
temp1:            N/A  

それっぽい出力結果になりましたが、まだ何か違ってます。
CPU コア 6 個分の温度表示が無いし、FAN の回転数も得られてません。

◆ it87 モジュールを最新にしてみる

前述した sensors-detect の出力結果からChip `ITE IT8686E Super IO Sensors'が解決できてない件について調べたところ「it87 モジュールを最新にすれば良い」との事なので、試してみます。

$ cd ~/work
$ git clone https://github.com/a1wong/it87.git
Cloning into 'it87'...
remote: Enumerating objects: 458, done.
remote: Total 458 (delta 0), reused 0 (delta 0), pack-reused 458
Receiving objects: 100% (458/458), 200.04 KiB | 388.00 KiB/s, done.
Resolving deltas: 100% (277/277), done.
$ cd it87
$ sudo make dkms

Creating symlink /var/lib/dkms/it87/v1.0-48-g40bec4b/source ->
                 /usr/src/it87-v1.0-48-g40bec4b

DKMS: add completed.

Kernel preparation unnecessary for this kernel.  Skipping...

Building module:
cleaning build area...
make -j12 KERNELRELEASE=5.8.0-25-generic TARGET=5.8.0-25-generic...
Signing module:
 - /var/lib/dkms/it87/v1.0-48-g40bec4b/5.8.0-25-generic/x86_64/module/it87.ko
Secure Boot not enabled on this system.
cleaning build area...

DKMS: build completed.

it87.ko:
Running module version sanity check.
 - Original module
   - No original module exists within this kernel
 - Installation
   - Installing to /lib/modules/5.8.0-25-generic/updates/dkms/

depmod..........

DKMS: install completed.

正常終了したら、一旦 it87 モジュールを解除して、再度ロードします。
最新モジュールにしたら sensors を実行確認します。

$ sudo modprobe -r it87
$ sudo modprobe it87
$ sensors
it8686-isa-0a40
Adapter: ISA adapter
in0:         768.00 mV (min =  +0.00 V, max =  +3.06 V)
in1:           2.00 V  (min =  +0.00 V, max =  +3.06 V)
in2:           2.00 V  (min =  +0.00 V, max =  +3.06 V)
in3:           2.02 V  (min =  +0.00 V, max =  +3.06 V)
in4:         924.00 mV (min =  +0.00 V, max =  +3.06 V)
in5:         888.00 mV (min =  +0.00 V, max =  +3.06 V)
in6:           1.20 V  (min =  +0.00 V, max =  +3.06 V)
3VSB:          3.26 V  (min =  +0.00 V, max =  +6.12 V)
Vbat:          3.26 V  
fan1:         385 RPM  (min =    0 RPM)
fan2:           0 RPM  (min =    0 RPM)
fan3:           0 RPM  (min =    0 RPM)
fan4:           0 RPM  (min =    0 RPM)
fan5:           0 RPM  (min =    0 RPM)
temp1:        +29.0°C  (low  = +127.0°C, high = +127.0°C)  sensor = thermistor
temp2:        +32.0°C  (low  = +127.0°C, high = +127.0°C)  sensor = thermistor
temp3:        +31.0°C  (low  = +127.0°C, high = +127.0°C)  sensor = AMD AMDSI
temp4:        +31.0°C  (low  = +127.0°C, high = +127.0°C)  sensor = thermistor
temp5:        +35.0°C  (low  =  +0.0°C, high = -120.0°C)  sensor = thermistor
temp6:        +41.0°C  (low  =  +0.0°C, high = -120.0°C)  sensor = thermistor
intrusion0:  ALARM

k10temp-pci-00c3
Adapter: PCI adapter
Vcore:       788.00 mV 
Vsoc:        925.00 mV 
Tctl:         +31.6°C  
Tdie:         +31.6°C  
Icore:         7.00 A  
Isoc:          7.75 A  

it8792-isa-0a60
Adapter: ISA adapter
in0:         414.00 mV (min =  +0.00 V, max =  +2.78 V)
in1:         948.00 mV (min =  +0.00 V, max =  +2.78 V)
in2:           1.08 V  (min =  +0.00 V, max =  +2.78 V)
+3.3V:         3.36 V  (min =  +0.00 V, max =  +5.56 V)
in4:           1.30 V  (min =  +0.00 V, max =  +2.78 V)
in5:           1.17 V  (min =  +0.00 V, max =  +2.78 V)
in6:           2.78 V  (min =  +0.00 V, max =  +2.78 V)  ALARM
3VSB:          3.33 V  (min =  +0.00 V, max =  +5.56 V)
Vbat:          3.38 V  
fan1:           0 RPM  (min =    0 RPM)
fan2:           0 RPM  (min =    0 RPM)
fan3:           0 RPM  (min =    0 RPM)
temp1:        +28.0°C  (low  = +127.0°C, high = +127.0°C)  sensor = thermistor
temp2:        +33.0°C  (low  = +127.0°C, high = +127.0°C)  sensor = thermistor
temp3:        +34.0°C  (low  = +127.0°C, high = +127.0°C)  sensor = thermistor
intrusion0:  ALARM

iwlwifi_1-virtual-0
Adapter: Virtual device
temp1:            N/A  

ようやく思ってたような出力結果が得られました。

最後に /etc/modules へ it87 を追記すれば作業完了です。

再起動して sensors を実行したところ、期待通りの出力結果になりました。

◆ 参考にしたサイト

※追記 2023-10-22

先日 BIOS を F64e まで更新し、OS のアップデートを実行しました。
その後、sensors を実行すると温度が正常に表示されません。

$ sensors
iwlwifi_1-virtual-0
Adapter: Virtual device
temp1:            N/A  

acpitz-acpi-0
Adapter: ACPI interface
temp1:        +16.8°C  (crit = +20.8°C)

k10temp-pci-00c3
Adapter: PCI adapter
Tctl:         +49.5°C  

対策として、/etc/modprobe.d/it87.confを用意します。

・ファイル: /etc/modprobe.d/it87.conf

options it87 ignore_resource_conflict=1

後は PC を再起動して、sensors を実行すると元通り表示されるはずです。