参考:以下问题 驱动器名称? “/dev/sda”的“sda”部分的正确术语是什么?
鉴于:
- 我有一个系统(在本例中是 Raspberry Pi,但这可能与任何 'nix 系统相关。)
- 它正在运行一个 Linux 版本,并且可以假设所有正常的 Linux 命令都可以工作。
- 启动设备可以是 SD 卡或 USB 连接存储设备。
- 如果从连接的存储设备启动,则设备“基本名称”为 sd(x)
- 如果从 SD 卡启动,设备“basename”将变为类似“mm(xxxx)”
我想要做什么:我希望能够以编程方式(如果可能的话,在 shell 脚本中)启动它的设备类型,并根据启动设备更改某些特征。
简单的例子:
Boot device = "mmxxxxx"
Print "Booted from SD card!"
Boot device = "sda"
Print "Booted from Attached Storage!"
我想要做的是提取根分区所源自的主要设备类型(为了需要一个更好的术语)(IE“sd”、“mm”或其他任何名称,具体取决于安装为根分区的设备。)
我怀疑我可以以某种方式列出安装在根目录上的设备,没有列出所有内容mount
,然后提取最后一个斜杠后面的前两个字母。 。 。
答案1
挂载点由 systemd 控制。
您可以通过以下方式列出 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
更好,正如指出的那样@steeldriver在这个评论:
systemctl show --value --property=What -- -.mount |xargs basename
男人systemd.mount
:
What:
获取要挂载的设备节点、文件或其他资源的绝对路径。
答案2
这是一个不依赖于Linux的答案系统(需要/sys
安装才能lsblk
使用以及jq
解析结果的命令)。
知道它lsblk
已经包含了找出树输出中的依赖关系的所有逻辑,我想知道如何利用它来完成任务。使用--inverse
首先显示叶子(但还不能将叶子作为参数),以便/
首先使用安装点进行过滤。然后--json
可以迭代找到结果。
它输出最终的设备名称,绕过 LVM、LUKS 等的任何层(在磁盘分区中使用 / over LV over LUKS 的系统进行测试)。未使用 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
您可以使用 elif 结构来代替 else,例如:
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 命令执行此操作,因此我将其作为答案发布。