Bash - 将 kpartx 输出提取到变量



我想从 kpartx 工具中提取输出:

add map loop18p1 (253:0): 0 1048576 linear 7:18 2048
add map loop18p2 (253:1): 0 1046528 linear 7:18 1050624

然后将 loop18p1 和 loop18p2 保存到 $a 并$b。

kpartx="$(sudo kpartx -av $IMAGE_FILE)"
read PART_FAT32 PART_NTFS <<<$(grep -o 'loop.p.' <<<"$kpartx")
a=/dev/mapper/$PART_FAT32
b=/dev/mapper/$PART_NTFS
echo $a
echo $b

但不知何故它似乎不起作用,我总是得到空变量:

/dev/mapper/
/dev/mapper/

亲切问候

贾梅芬

我打算继续研究这个问题,但查尔斯·达菲突然加入并通过评论说了几乎同样的话,所以我就把这个留在这里留给后人。 我的目标是完成诊断问题的过程。

让我们演练一下您的代码。 我将使用此图像进行测试。

你从这个开始:

kpartx="$(sudo kpartx -av $IMAGE_FILE)"

在我的系统上,这意味着:

$ IMAGE_FILE=2018-11-13-raspbian-stretch-lite.img
$ kpartx="$(sudo kpartx -av $IMAGE_FILE)"
$ echo "$kpartx"
loop3p1 : 0 89854 /dev/loop3 8192
loop3p2 : 0 3547136 /dev/loop3 98304

您的输出可能看起来不同,但这应该足以让我们测试代码的其余部分。

接下来,您尝试使用嵌套<<<表达式从 $kpartx 变量中提取设备名称:

$ read PART_FAT32 PART_NTFS <<<$(grep -o 'loop.p.' <<<"$kpartx")

这让我:

$ echo $PART_FAT32
loop3p1
$ echo $PART_NTFS

换句话说,$PART_NTFS是空的。 这是因为read只在一行上运行,而您的grep命令输出多行。 grep -o 'loop.p.' <<<"$kpartx"的结果是:

$ grep -o 'loop.p.' <<<"$kpartx"
loop3p1
loop3p2

因此,您需要重构提取这些值的方式。

loop.p. 不匹配loop18p1loop18p2至少,您需要将grep修复为类似于grep -E -o 'loop[[:digit:]]+p[[:digit:]]+'的内容(+是"一个或多个"修饰符;因此[[:digit:]]+匹配POSIX ERE中的一个或多个数字,这是grep -E启用的语法(。

不过,更好的是了解您正在阅读的内容的语法,而不仅仅是试图盲目匹配内容。

{
  read -r _ _ part_fat32 _  # first line:  read third word into part_fat32
  read -r _ _ part_ntfs _   # second line: read third word into part_ntfs
} < <(sudo kpartx -av "$IMAGE_FILE")
a="/dev/mapper/$part_fat32"
b="/dev/mapper/$part_ntfs"

如果您更喜欢更通用的方式,则可以对设备字母使用动态变量。注意:如果 kpartx 无法映射,stderr 也会重定向到 grep。数组的声明取决于外壳。

# dynamic variable list for device letters
declare -a DEV=({a..z})
# assign kpartx results to device letters
for PART in $(sudo kpartx -av "$IMAGE_FILE" 2>&1 | grep -owE '(loop[0-9]+p[0-9]+)')
  do
    eval ${DEV[${i:-0}]}=/dev/mapper/$PART
    i=$((${i:-0}+1))
done
echo $a
echo $b

最新更新