I want to:
More concretely:
#! /bin/bash
target_ORG=$(ls /usr/local/etc/ini/system/ORG)
target_DOMAIN=$(ls /usr/local/etc/ini/system/DOMAIN)
target_SITE=$(ls /usr/local/etc/ini/system/SITE)
target_DEVICE=$(ls /usr/local/etc/ini/system/DEVICE)
target_VOLUME=$(ls /usr/local/etc/ini/system/VOLUME)
target_HOST=$(ls /usr/local/etc/ini/system/HOST)
instanceList=$(ls /dev/disk/by-partlabel)
for i in $instanceList
do
instance_ORG=${i:0:3}
instance_DOMAIN=${i:4:3}
instance_SAN=${i:8:1}
instance_SITE=${i:10:1}
instance_DEVICE=${i:12:5}
instance_VOLUME=${i:18:6}
<PSEUDOCODE>
Compare the instance_* strings with the target_* strings
IF they all match
THEN
mount $i /path/to/mountpoint
</PSEUDOCODE>
done
Where:
the specific devices available vary across time
the partlabel format is: xxx-xxx-x-x-xxxxx-xxxxxx (e.g. 001-001-1-1-00001-000001), indicating a disk partition as being ORG-DOMAIN-SAN-SITE-DEVICE-VOLUME
the /usr/local/etc/ini/system/* directories each contain a file named for the corresponding substring - allowing changes to be made by simply renaming (rather than having to manipulate the content of) files
/path/to/mountpoint is the mountpoint for the matching $instance_SAN
That is ...
xxx-xxx-1-x-xxxxx-xxxxxx mounts to /path/to/1
xxx-xxx-2-x-xxxxx-xxxxxx mounts to /path/to/2
xxx-xxx-3-x-xxxxx-xxxxxx mounts to /path/to/3
The problem with the for loop is that it will simply assign the next value to the $instance_* variable, when I want it to keep the first found instance - so, xxx-xxx-1-1-xxxxx-xxxxxx will be overmounted with xxx-xxx-1-2-xxxxx-xxxxxx and so on.
A case test will find and keep the first found instance, but won't then iterate over the rest of $instanceList
e.g. given
/usr/local/etc/ini/system/ORG/001
/usr/local/etc/ini/system/DOMAIN/001
/usr/local/etc/ini/system/SITE/1
/usr/local/etc/ini/system/DEVICE/00001
/usr/local/etc/ini/system/VOLUME/000001
/usr/local/etc/ini/system/HOST/000001
...and...
*$instanceList* of:
001-001-1-1-00001-000001
001-001-1-1-00001-000002
001-001-1-2-00001-000001
001-001-1-2-00001-000002
001-001-2-2-00001-000001
001-001-2-2-00002-000001
001-001-3-5-00001-000002
001-001-1-1-00001-000001 will get mounted to /path/to/1
and everything else will be ignored.
e.g. given the above
001-001-1-1-00001-000001 should be mounted to /path/to/1
001-001-1-1-00001-000002 should be ignored
001-001-1-2-00001-000001 should be ignored
001-001-1-2-00001-000002 should be ignored
001-001-2-2-00001-000001 should be mounted to /path/to/2
001-001-2-2-00002-000001 should be ignored
001-001-3-5-00001-000002 should be mounted to /path/to/3
Nested if tests are too brittle.
Multiple case tests could work
<PSEUDOCODE>
Case of $instance_SAN=1: mount device/partion to /path/to/$instance_SAN
Case of $instance_SAN=2: mount device/partion to /path/to/$instance_SAN
Case of $instance_SAN=3: mount device/partion to /path/to/$instance_SAN
</PSEUDOCODE>
But I just can't wrap my head around how to iterate across $instanceList without simply breaking after the first match.
I realise this is probably very basic, but my bash just isn't very advanced, I'm afraid.
I'd like to avoid solutions such as autoFS, however, so that the approach isn't reliant upon anything more than a core Linux install; even something like a minimal Arch/Gentoo, or even LFS, should be able to provision everything without the need for any extra utilities - also, this has to be done pre-login, so, I don't think a 'third party' solution would work anyway.
=======
UPDATE
=======
Following the suggestion, by pjh, to try mountpoint || mount
...
#! /bin/bash
target_ORG=$(ls '/usr/local/etc/ini/system/ORG')
target_DOMAIN=$(ls 'usr/local/etc/ini/system/DOMAIN')
target_SITE=$(ls '/usr/local/etc/ini/system/SITE')
target_DEVICE=$(ls '/usr/local/etc/ini/system/DEVICE')
target_VOLUME=$(ls '/usr/local/etc/ini/system/VOLUME')
target_HOST=$(ls '/usr/local/etc/ini/system/HOST')
echo "target_ORG=$target_ORG"
echo "target_DOMAIN=$target_DOMAIN"
echo "target_SITE=$target_SITE"
echo "target_DEVICE=$target_DEVICE"
echo "target_VOLUME=$target_VOLUME"
echo "target_HOST=$target_HOST"
instanceList=$(ls /dev/disk/by-partlabel)
for i in {1..3}
do
for n in $instanceList
do
echo -e '\n'
echo "i = $i"
echo "n = $n"
instance_ORG=${n:0:3}
instance_DOMAIN=${n:4:3}
instance_SAN=${n:8:1}
instance_SITE=${n:10:1}
instance_DEVICE=${n:12:5}
instance_VOLUME=${n:18:6}
mountpoint "/mnt/test/$i" || mount "$n" "/mnt/test/$i"
done
done
... results in
target_ORG=000
target_DOMAIN=000
target_SITE=1
target_DEVICE=00000
target_VOLUME=000001
target_HOST=000001
i = 1
n = 000-000-1-1-00000-000001
/mnt/test/1 is not a mountpoint
mount: /mnt/test/1: special device 000-000-1-1-00000-000001 does not exist.
i = 1
n = 000-000-2-1-00000-000001
/mnt/test/1 is not a mountpoint
mount: /mnt/test/1: special device 000-000-2-1-00000-000001 does not exist.
i = 1
n = 000-000-3-1-00000-000001
/mnt/test/1 is not a mountpoint
mount: /mnt/test/1: special device 000-000-3-1-00000-000001 does not exist.
i = 2
n = 000-000-1-1-00000-000001
/mnt/test/2 is not a mountpoint
mount: /mnt/test/2: special device 000-000-1-1-00000-000001 does not exist.
i = 2
n = 000-000-2-1-00000-000001
/mnt/test/2 is not a mountpoint
mount: /mnt/test/2: special device 000-000-2-1-00000-000001 does not exist.
i = 2
n = 000-000-3-1-00000-000001
/mnt/test/2 is not a mountpoint
mount: /mnt/test/2: special device 000-000-3-1-00000-000001 does not exist.
i = 3
n = 000-000-1-1-00000-000001
/mnt/test/3 is not a mountpoint
mount: /mnt/test/3: special device 000-000-1-1-00000-000001 does not exist.
i = 3
n = 000-000-2-1-00000-000001
/mnt/test/3 is not a mountpoint
mount: /mnt/test/3: special device 000-000-2-1-00000-000001 does not exist.
i = 3
n = 000-000-3-1-00000-000001
/mnt/test/3 is not a mountpoint
mount: /mnt/test/3: special device 000-000-3-1-00000-000001 does not exist.
And ls -l /dev/disk/by-partlabel
lists a b
the first column - so it doesn't seem to be that they aren't recognised as block devices either.
Am I running into the issue referred to by Cyrus? (I can't find anything else that seems to hint at the cause).
FWIW ...
DMESG reports some errors
[ 7064.170224] pcieport 0000:00:1c.0: AER: Corrected error received: 0000:00:1c.0
[ 7064.170242] pcieport 0000:00:1c.0: PCIe Bus Error: severity=Corrected, type=Physical Layer, (Receiver ID)
[ 7064.170247] pcieport 0000:00:1c.0: device [8086:a115] error status/mask=00000001/00002000
[ 7064.170254] pcieport 0000:00:1c.0: [ 0] RxErr (First)
...
[11372.230786] 000-000-1-1-00000-000001: Can't open blockdev
[11372.232977] 000-000-2-1-00000-000001: Can't open blockdev
[11372.235242] 000-000-3-1-00000-000001: Can't open blockdev
export "$n"
The result was
export: '000-000-3-1-00000-000001': not a valid identifier
Changing the PARTLABEL to remove the '-' symbols resulted in
export: '0000003100000000001: not a valid identifier
So, unless my export is incorrect, it's not those either.
Changed it to
export N="$n"
and
export "N=$n"
There was no error this time, but echoing $N returned a null output.
[SOLUTION]
#! /bin/bash
target_ORG=$(ls '/usr/local/etc/ini/system/ORG')
target_DOMAIN=$(ls '/usr/local/etc/ini/system/DOMAIN')
target_SITE=$(ls '/usr/local/etc/ini/system/SITE')
target_DEVICE=$(ls '/usr/local/etc/ini/system/DEVICE')
target_VOLUME=$(ls '/usr/local/etc/ini/system/VOLUME')
target_HOST=$(ls '/usr/local/etc/ini/system/HOST')
instanceList=$(ls '/dev/disk/by-partlabel')
for i in {1..3} ; do
for n in $instanceList ; do
instance_ORG=${n:0:3}
instance_DOMAIN=${n:4:3}
instance_SAN=${n:8:1}
instance_SITE=${n:10:1}
instance_DEVICE=${n:12:5}
instance_VOLUME=${n:18:6}
mountpoint -q /path/to/$i || mount /dev/disk/by-partlabel/$instance_ORG\-$instance_DOMAIN\-$i\-$instance_SITE\-$instance_DEVICE\-$instance_VOLUME /path/to/$i >/dev/null 2>&1
done
done
To specify a specific subset from the available devices, substitute $target_*
for $instance_*
in the mount
command