0
for i in $(virsh list --all | awk '{print $2}'|grep -v Name);
  do
    virsh domblklist $i --details | awk '{print $4}'|grep -v Source;
  done

I get

/sdc/kvm_strage/vm1.qcow2
/sdc/kvm_strage/vm1_1.qcow2
-


/sdc/kvm_strage/vm2.qcow2
-


/sdc/kvm_strage/vm3.qcow2
/sdc/kvm_strage/vm3_1.qcow2
-

But I want to get the path in a array and exclude the "-" like

my_array=(/sdc/kvm_strage/vm1.qcow2 /sdc/kvm_strage/vm1_1.qcow2 /sdc/kvm_strage/vm2.qcow2 /sdc/kvm_strage/vm3.qcow2 /sdc/kvm_strage/vm3_1.qcow2)

How to do that?

fteinz
  • 1,085
  • 5
  • 15
  • 30
  • Add output of `virsh list --all` and your desired output (no description) for that sample input to your question (no comment). – Cyrus Sep 07 '19 at 05:01

2 Answers2

1

Here is an alternative way:

declare -a my_array=($(for vm in $(virsh list --all --name); do
    virsh domblklist $vm --details | awk '/disk/{print $4}'
done))

EDIT: I just noticed I missed a pair of parenthesis when setting the value of my_array.

accdias
  • 5,160
  • 3
  • 19
  • 31
0

You can skip the 2 header lines with tail --lines=+3, to avoid capturing the column titles and dash line separator header.

This is how a virsh list --all look like:

2 header lines to skip with tail --lines=+3:

 Id    Name                           State
----------------------------------------------------

Data to parse:

 1     openbsd62                      running
 2     freebsd11-nixcraft             running
 3     fedora28-nixcraft              running

After it skip the header line of the domains list, the script below iterates over each domain in a while read loop witch receives its data from the virsh list --all | tail --lines=+3 | awk '{print $2}'

Then inside the while loop, it maps the output of virsh domblklist "$domain" --details | tail --lines=+3 | awk '{print $4}' into the temporary file-mapped array MAPFILE;
and add the MAPFILE array entries to my_array

After execution, my_array contains all block devices from all domains.

#!/usr/bin/env bash

declare -a my_array=() # array of all block devices

# Iterate over domains that are read from the virsh list
while IFS= read -r domain; do
  mapfile < <( # capture devices list of domain into MAPFILE
    # Get block devices list of domain
    virsh domblklist "$domain" --details |

      # Start line 3 (skip 2 header lines)
      tail --lines=+3 |

        # Get field 4 s value
        awk '{print $4}'
  )
  my_array+=( "${MAPFILE[@]}" ) # Add the block devices paths list to my_array
done < <( # Inject list of domains to the while read loop
  # List all domains
  virsh list --all --name
)
Léa Gris
  • 17,497
  • 4
  • 32
  • 41