0

I'm new to shell scripting...can anyone tell me how I can check whether I am on the first element of the array in my very first 'if' statement? It seems to be making i into something other than an integer.

#! /bin/bash

namelist=($(lsblk -d -n -o NAME))
sizelist=($(lsblk -d -n -o SIZE))
seriallist=($(lsblk -d -n -o SERIAL))

IFS=$'\n'
modellist=($(lsblk -d -n -o MODEL))

echo "*********** HARD DRIVE DATA SCRIPT ***********"
echo "This script lets you choose the hard drives"
echo " "
echo "********************************************"
echo "* Step one: Choose your hard drive         *"
echo "********************************************"

for i in "${namelist[@]}"
do
    if [ "$i" -eq "0" ]
    then
        echo "First hard drive:"
    else
        echo "Next hard drive:"
    fi
    echo "* Size: ${sizelist[$i]}B"
    echo "* Model: ${modellist[$i]}"
    echo "* Serial number: ${seriallist[$i]}"
    echo "* Linux device name: ${namelist[$i]}"
    echo "* Partition List:"
    echo "Number  Name  Formatted as"
    lsblk -n -o NAME,LABEL,FSTYPE /dev/${namelist[$i]} | tail -n +2
    ((i++))
done
1
  • 2
    That for loop will loop over the elements, i.e. in the first iteration i=${namelist[0]} and not i=0 If you want to loop over the indices, use for i in "${!namelist[@]}" Commented Nov 5, 2015 at 23:32

1 Answer 1

1
i=0
for item in "${namelist[@]}"
do
    echo $item # so you can see what your assumption actually is
    if [ "$i" -eq "0" ]
    then
        echo "First hard drive:"
    else
        echo "Next hard drive:"
    fi
    echo "* Size: ${sizelist[$i]}B"
    echo "* Model: ${modellist[$i]}"
    echo "* Serial number: ${seriallist[$i]}"
    echo "* Linux device name: ${namelist[$i]}"
    echo "* Partition List:"
    echo "Number  Name  Formatted as"
    lsblk -n -o NAME,LABEL,FSTYPE /dev/${namelist[$i]} | tail -n +2
    ((i++))
done

You're mixing up for syntaxes. item refers here to each element of the array, not i the counter. Note that it won't work unless you get serials for each device that you end up with, which you probably won't. In other words, you are assuming the counts of each array you generated is the same, that's not necessarily the case here. I get 0 results for serial in my system, for example, whether as root or as normal user. The only way I know to get serials is far more complex than you have here, so I won't attempt describe it, and it also won't always return values for your serials for each device.

Also note that you will get results for fdx and srx with this logic, that is, floppy drives and optical drives, which you probably don't want.

I also tested, and get nothing for LABEL FSTYPE either, by the way. So this method wouldn't work on a Debian type system, I can't speak for others.

If you were to use:

for i in "${!namelist[@]}"

then you would not use ((i++)), which is only required if nothing else is changing i.

This would work better using awk, which is designed to create such reports, but that's outside the scope of your question.

Sign up to request clarification or add additional context in comments.

2 Comments

I've been using lsblk for about 30-40 hard drives and I've always gotten a serial number...but I'll keep that in mind and change my code accordingly. I know another way to do it is smartctl -a | grep "Serial"
You can always use inxi -Dxxx for serials and disk information, unless you just want a learning experience, which is always of value as well.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.