0

I am trying to do the following in a bash script: add all the device node files which don't start with /dev/sda to an array called devices. As the script will be executed on a read-only filesystem, I cannot use here documents.

Here is my code:

devices=()
ls -1 /dev/hd* /dev/sd* | while read -r device; do
    if [[ "$device" != "/dev/sda"* ]]; then
        devices+=($device)
    fi
done

I don't understand why, at the end of the commands, devices is still empty. For example, I can successfully print each item just by adding the command echo $device before/after adding it to the array. But why don't they get added?

Also, if I run the same commands using here documents everything works fine:

devices=()
while read -r device; do
    if [[ "$device" != "/dev/sda"* ]]; then
        devices+=($device)
    fi
done <<< $(ls -1 /dev/hd* /dev/sd*)

At the end of these commands the array devices is correctly filled.

Can you help me understand why the first code extract doesn't work while the second one does? What am I doing wrong?

Cyrus
  • 84,225
  • 14
  • 89
  • 153
user2747949
  • 163
  • 1
  • 6
  • 13

2 Answers2

0

Alright. I solved my problem by using bash Process Substitution:

devices=()
while read -r device; do
    if [[ "$device" != "/dev/sda"* ]]; then
        devices+=($device)
    fi
done < <(ls -1 /dev/hd* /dev/sd*)

This way it works.

user2747949
  • 163
  • 1
  • 6
  • 13
0

You don't need to use ls, read, or process substitution. Just use a for loop.

devices=( /dev/hd* )
for device in /dev/sd*; do
    [[ $device != /dev/sda* ]] && devices+=("$device")
done

In fact, with extended patterns, you don't even need a loop.

shopt -s extglob
devices=( /dev/hd* /dev/sd!(a)* )
chepner
  • 497,756
  • 71
  • 530
  • 681