注:次の質問 ドライブ名? 「/dev/sda」の「sda」部分の正しい用語は何ですか?
一方:
- 私はシステムを持っています(この場合はRaspberry Piですが、これはすべてのnixシステムに関連付けることができます)。
- Linuxバージョンを実行しており、すべての一般的なLinuxコマンドが機能しているとします。
- ブートデバイスはSDカードまたはUSB接続ストレージデバイスです。
- 接続されたストレージデバイスから起動する場合、デバイス「basename」はsd(x)です。
- SDカードから起動すると、デバイス「basename」は「mm(xxxx)」のように変わります。
私がやりたいこと:プログラムで(可能であればシェルスクリプトで)デバイスタイプでそれを実行し、実行されたデバイスに応じて特定の属性を変更できるようにしたいです。
簡単な例:
Boot device = "mmxxxxx"
Print "Booted from SD card!"
Boot device = "sda"
Print "Booted from Attached Storage!"
私が望むのは、ルートパーティションが起動されたデフォルトのデバイスタイプ(より良い用語で)を抽出することです(つまりルートパーティションとしてマウントされたデバイスに応じて、「sd」、「mm」、またはその他の名前。 )
ルートディレクトリにマウントされたデバイスを何らかの方法で一覧表示できるようです。すべてがリストされているわけではありません。mount
を選択し、最後のスラッシュの後の最初の2文字を抽出します。 。 。
答え1
マウントポイントは systemd によって制御されます。
以下では、システムマウントユニットファイルを一覧表示できます。
systemctl list-units --type=mount --all
出力例:
-.mount loaded active mounted Root Mount
boot-efi.mount loaded active mounted /boot/efi
...
ルートパーティションはによって制御されます-.mount
。
systemctl status -- -.mount
● -.mount - Root Mount
Loaded: loaded (/etc/fstab; generated)
Active: active (mounted) since Wed 2024-02-07
Where: /
What: /dev/sdaX
Docs: man:fstab(5)
man:systemd-fstab-generator(8)
デバイス名を抽出するには:
systemctl status -- -.mount |grep -oP '(?<=What: ).*' |xargs basename
systemctl show --value --property=What -- -.mount |xargs basename
男性systemd.mount
:
What:
マウントするデバイスノード、ファイル、またはその他のリソースへの絶対パスを取得します。
答え2
Linuxに依存しない答えは次のとおりです。システム(コマンド結果を使用して解析する/sys
にはインストールが必要です。)lsblk
jq
lsblk
ツリー出力で依存関係を見つけるためのすべてのロジックがすでに含まれていることがわかっているので、これを活用して作業を実行する方法がわかります。最初にマウントポイントでフィルタリングする--inverse
には、Show Leaves First(まだパラメータとしては使用されません)を使用します。/
その後、結果を--json
繰り返し見つけることができます。
LVM、LUKSなどのすべてのレイヤーをバイパスして最終デバイス名を出力します(ディスクパーティションでLUKSより/over LVを使用するシステムでテストされます)。 RAIDでテストされていません(複数のデバイスを出力したかったです。そうしないと、このjq
スクリプトは失敗します)。
これは非常に長い行です:
lsblk --json --tree --inverse | jq -r '.blockdevices[] | if .mountpoints[] == "/" then ( .. | if .children? then empty else if .name then .name else empty end end ) else empty end'
または読みやすくなります。
lsblk --json --tree --inverse |
jq -r '
.blockdevices[] |
if .mountpoints[] == "/" then
.. |
if .children? then
empty
else
.name // empty
end
else
empty
end
'
最初の一致を受け入れ/
、..
オブジェクトに子オブジェクト(別名"children"
固有の型の子オブジェクト)が含まれなくなるまで、オブジェクトに対して繰り返し(使用)してからその名前を表示します。
結果の最初の2文字だけを取得するには、さらに| cut -c-2
。
答え3
df /
獲得に使用される機器です/
。列(--output=source
)と行()に基づいてtail -1
フィルタリングすることもできます。
% df --output=source / | tail -1
/dev/mapper/sys-root
答え4
これは簡単な方法です。私はこれを私のコンピュータでのみテストしました。インストールコマンドの出力が異なる場合があります。
boot_device=( $(mount | grep boot) )
if [[ $(echo "${boot_device[0]}" | grep -c sd) -eq 1 ]]
then
echo "Booted from attached storage"
else
echo "Booted from SD card!"
fi
else の代わりに elif 構造を使用できます。たとえば、次のようになります。
elif [[ $(echo "${boot_device[0]}" | grep -c mm) -eq 1 ]]
then
echo "Booted from SD card!"
else
echo "ERROR: Something has gone horribly wrong!"
fi
答えを受け入れましたが、mountコマンドを使用してこれを行う方法を理解するのに数分かかりました。