我有一个标准的 ubuntu 加密 lvm 设置。/dev/sda3
使用 LUKS 加密。该 LUKS 容器内有一个 LVM(位于/dev/mapper/dm_crypt-0
),该 LVM 内有一个从/dev/ubuntu-vg/ubuntu-lv
到挂载的文件系统/
如何在 bash 中用一行代码将已知的挂载点转换/
为,最好不使用 root?如果可以做到这一点,我很乐意安装一个单独的实用程序。/dev/sda3
我已经想好了df|tail -n +2|cut -f 1 -d
要怎么做/dev/mapper/ubuntu--vg-ubuntu--lv
,但是我该如何做/dev/sda3
呢?
答案1
可能有更简单、更有效的方法来做到这一点,但我能够使用、和来实现您想要的,lsblk
而不需要 root 访问权限。grep
awk
总结
pkname=$(lsblk -o MOUNTPOINT,PKNAME | grep "^/"[^[:alnum:]] | awk '{ print $2 }');pkname=$(lsblk -o PATH,PKNAME,KNAME | grep $pkname | awk -v val="$pkname" '$3 == val { print $2 }');lsblk -o PATH,KNAME | grep $pkname | awk '{ print $1 }';unset pkname
让我们分解一下,使用测试虚拟机 Ubuntu 22.04.3 Server 作为示例。从 的输出开始lsblk
。如您所见,您想要的所有信息都在那里。它显示了挂载点和到 的树的路径。挑战在于如何解析此输出以获取从挂载点 开始的/dev/sda3
路径。/dev/sda3
/
$ lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
loop0 7:0 0 63.4M 1 loop /snap/core20/1974
loop1 7:1 0 111.9M 1 loop /snap/lxd/24322
loop2 7:2 0 53.3M 1 loop /snap/snapd/19457
sda 8:0 0 25G 0 disk
├─sda1 8:1 0 1M 0 part
├─sda2 8:2 0 2G 0 part /boot
└─sda3 8:3 0 23G 0 part
└─dm_crypt-0 253:0 0 23G 0 crypt
└─ubuntu--vg-ubuntu--lv 253:1 0 23G 0 lvm /
sr0 11:0 1 1024M 0 rom
幸运的是,lsblk
有一个-o
选项允许您提供要打印的列的列表。这会显示可以使用grep
和解析的附加信息awk
。查看lsblk --help
完整列表。首先,我选择了MOUNTPOINT
和PKNAME
,但稍后我也会使用PATH
和KNAME
。
$ lsblk --help
--snip--
KNAME internal kernel device name
PATH path to the device node
--snip--
MOUNTPOINT where the device is mounted
--snip--
PKNAME internal parent kernel device name
--snip--
1. 找到PKNAME
挂载点:/
以下行打印与挂载点关联的MOUNTPOINT
信息:PKNAME
/
$ lsblk -o MOUNTPOINT,PKNAME | grep "^/"[^[:alnum:]]
/ dm-0
用于awk
打印并将第二列分配PKNAME
给变量:
$ pkname=$(lsblk -o MOUNTPOINT,PKNAME | grep "^/"[^[:alnum:]] | awk '{ print $2 }')
$ echo $pkname
dm-0
2. 找到上PKNAME
一个PKNAME
再次使用lsblk
,这次以PATH
、PKNAME
和KNAME
作为列。使用grep
查找包含 值的行$pkname
:
$ lsblk -o PATH,PKNAME,KNAME | grep $pkname
/dev/mapper/dm_crypt-0 sda3 dm-0
/dev/mapper/ubuntu--vg-ubuntu--lv dm-0 dm-1
这会产生两个匹配项,但我们只想要$pkname
匹配第 3 列的匹配项,即。必须包含KNAME
第 2 列,因为这是下一个需要的值。PKNAME
再次使用awk
来获取该值,并将其重新分配给您的变量:
$ pkname=$(lsblk -o PATH,PKNAME,KNAME | grep $pkname | awk -v val="$pkname" '$3 == val { print $2 }')
$ echo $pkname
sda3
3. 找到上PATH
一个PKNAME
使用lsblk
显示PATH
和KNAME
列,grep
查找匹配的行,并awk
打印第一列PATH
:
$ lsblk -o PATH,KNAME | grep $pkname | awk '{ print $1 }'
/dev/sda3
最后,将所有命令组合在一起,用分号分隔。为了完整起见,在unset
末尾添加一个以清除变量$pkname
。这是您的一行代码,无需 root 访问权限。
$ pkname=$(lsblk -o MOUNTPOINT,PKNAME | grep "^/"[^[:alnum:]] | awk '{ print $2 }');pkname=$(lsblk -o PATH,PKNAME,KNAME | grep $pkname | awk -v val="$pkname" '$3 == val { print $2 }');lsblk -o PATH,KNAME | grep $pkname | awk '{ print $1 }';unset pkname
/dev/sda3