Home > Software design >  return nvme list as array using jq and loop thru it
return nvme list as array using jq and loop thru it

Time:12-04

This is how I am grabbing all the NVME volumes:

all_nvme_volumes=$(sudo nvme list -o json | jq .Devices[].DevicePath)

This how the output looks like:

"/dev/nvme0n1" "/dev/nvme1n1" "/dev/nvme2n1" "/dev/nvme3n1" "/dev/nvme4n1" "/dev/nvme6n1"

How do I loop thru them process them individually?

I tried for r in "${all_nvme_volumes[@]}"; do echo "Device Name: $r"; done but the output is Device Name: "/dev/nvme0n1" "/dev/nvme1n1" "/dev/nvme2n1" "/dev/nvme3n1" "/dev/nvme4n1" "/dev/nvme6n1" which is one string instead of each element of array:

CodePudding user response:

Populating a bash array with mapfile from null delimited raw output from jq:

#!/usr/bin/env bash
mapfile -d '' all_nvme_volumes < <(
  sudo nvme list --output-format=json |
  jq --join-output '.Devices[].DevicePath   "\u0000"'
)

CodePudding user response:

A solution for bash < 4.4:

#!/bin/bash
IFS=$'\t' read -r -a all_nvme_volumes < <(
    sudo nvme list -o json | jq -r '[ .Devices[].DevicePath ] | @tsv'
)

note: device paths shouldn't be escaped by @tsv, so you won't need to unescape the values, but in case you use this trick for other purposes, you can unescape a value with printf -v value '%b' "$value"


How do I loop thru them process them individually?

Well, once you have the array, you can loop though its elements with:

for nvme_volume in "${all_nvme_volumes[@]}"
do
    # process "$nvme_volume"
done

But, if you only need to loop though the nvme volumes without storing them then you can use @LéaGris null delimiter method with a while loop:

#!/bin/bash
while IFS='' read -r -d '' nvme_volume
do
    # process "$nvme_volume"
done < <(sudo nvme list -o json | jq -j '.Devices[].DevicePath   "\u0000"')
  • Related