LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Newbie (https://www.linuxquestions.org/questions/linux-newbie-8/)
-   -   Why my bash script isn't partitioning the first two disks? (https://www.linuxquestions.org/questions/linux-newbie-8/why-my-bash-script-isnt-partitioning-the-first-two-disks-4175678859/)

maheshn0205 07-16-2020 05:43 PM

Why my bash script isn't partitioning the first two disks?
 
Hello All,

I'm in a weird situation, I developed a bash script which automatically does the disk partitions based the capacity. I have 62 drivers mix of TB and GB. When I ran the script, it is skipping the first two drivers (/dev/sda and /dev/sdb), rest are getting partitioned. Please see the link for the for the code or file which is attached. Your help is much appreciated.
https://pastebin.com/index/hFrAX6dn

Thank you All.

rnturn 07-16-2020 06:26 PM

Quote:

Originally Posted by maheshn0205 (Post 6146267)
Hello All,

I'm in a weird situation, I developed a bash script which automatically does the disk partitions based the capacity. I have 62 drivers mix of TB and GB. When I ran the script, it is skipping the first two drivers (/dev/sda and /dev/sdb), rest are getting partitioned. Please see the link for the for the code or file which is attached. Your help is much appreciated.
https://pastebin.com/index/hFrAX6dn

Thank you All.

Question: Why would you want/need a different partition table for disks whose size is reported in Gigabyte as opposed to Terabytes. For example: I have several older 1TB drives that are reported as 931.5 GB. I don't change the partition format according to size. (Though there may be a technical reason I do that in the future as spindle sizes grow.) Anyway, I'm just curious as to why you do this.

Can you list the output of:
Code:

for i in $(fdisk -l | grep -i 'Disk /dev/sd*' | awk '{print $2}'| sed 's/://' | sort );
do
        disk_size=$(fdisk -l | grep 'Disk /dev/sd*' | grep ${i} | awk '{print $3}')
        disk_capacity=$(fdisk -l | grep -i 'disk /dev/sd*' | grep ${i} |awk '{print $4}'|sed 's/,//')

        echo "$i : $disk_size : $disk_capacity"    # NOTE: Not in your script
done

(which is just your script minus the actual partitioning code.)

The above snippet works flawlessly on my system (though it shows fewer disks than you have). Can you run the above and show enough of the output to see whether disks "/dev/sd[ab]" are showing up (or not showing up if that's the case)?

I've included the case/esac block in a copy of your script and replaced the parted commands with "echo"s and is is running the correct "case" according to the value of "disk_capacity" and it's working correctly, too. No bugs there.

It would also be of some help to see what "fdisk -l" is producing for the disks "/dev/sd[ab]". I suspect that those two disks are not being processed because of something that "fdisk" is (or is not) returning.

Bottom line: your script seems OK. What "fdisk" is returning is probably the cause of your trouble. Are you seeing the "Check partition" messages. (BTW: You should include the disk name ("${i}") in that message to tie it to a specific device.)

syg00 07-16-2020 06:43 PM

Do your own basic debugging - echo all the variables as the are created, that way you know what is actually going on rather than guessing.
Seems remarkably complex - my general stance is that anything that pipes sed and/or grep to awk needs serious re-writing.

berndbausch 07-16-2020 08:03 PM

Quote:

Originally Posted by syg00 (Post 6146287)
Seems remarkably complex - my general stance is that anything that pipes sed and/or grep to awk needs serious re-writing.

Actually we have grep | awk | sed.

One reason why this is so complicated is fdisk. To simplify this, you could generate the list of disks with
Code:

cd /sys/block/
ls -d sd[a-z]

and their sizes with cat /sys/block/$DISK/size (in 512-bytes-blocks).

If you don't like /sys, you can also use lsblk, e.g.
Code:

lsblk --list --output name,size
as the basis of your calculations. You can add --bytes for a uniform format of the size column, no matter what disk size.

JJJCR 07-16-2020 08:56 PM

Quote:

disk_size=$(fdisk -l | grep 'Disk /dev/sd*' | grep ${i} | awk '{print $3}')
what's the output of grep ${i}?

add something like: echo "grep ${i}"

I think you will be able to see why there is a bypass.

Good luck!!

michaelk 07-16-2020 09:56 PM

I agree with the above comments. In addition,

You need to verify the actual size of the drive i.e a 4 TB drive might output 4000 GB and that needs to be formatted as gpt versus msdos.

Quote:

parted -s ${i} -a min mkpart primary xfs 0 ${disk_size}TB
While the command should work for either gpt or msdos "primary" is used in a different context depending on partition table type. msdos it really means create a primary partition, gpt it assigns the PARTLABEL=primary.

syg00 07-16-2020 10:24 PM

Truth be told there is no need for any of the contortions to calculate the size - parted accepts 100% as the end parameter.
Like I said, way too complicated.

berndbausch 07-16-2020 10:40 PM

Quote:

Originally Posted by syg00 (Post 6146325)
Truth be told there is no need for any of the contortions to calculate the size - parted accepts 100% as the end parameter.

True. I have not tried penetrating the thoughts that led to this script.
Code:

cd /sys/block
for disk in sd[a-z]
do
    parted -s ${disk} mklabel gpt
    parted -s ${disk} -a min mkpart primary xfs 0 100%
done

Much less byzantine (but not tested - all damage is your responsibility).

maheshn0205 07-17-2020 10:21 AM

1 Attachment(s)
Hello, Thank you for your reply. I did run the code snippet. I have attached a .txt file. Please take a look

maheshn0205 07-17-2020 10:32 AM

1 Attachment(s)
Quote:

Originally Posted by JJJCR (Post 6146309)
what's the output of grep ${i}?

add something like: echo "grep ${i}"

I think you will be able to see why there is a bypass.

Good luck!!

Thanks for your reply. when I did echo ${i}. I see /dev/sda and /dev/sdb are showing up, however when I run the variables individually I can still see those two drivers but when the script is ran, it is skipping them again. sda and sdb both are 9.1T drivers the same as other drives except two which are SSD's. I have attached the image of the output.

Thank you.

berndbausch 07-17-2020 09:42 PM

Quote:

Originally Posted by maheshn0205 (Post 6146504)
Hello, Thank you for your reply. I did run the code snippet. I have attached a .txt file. Please take a look

Can you share the script that generates this output?

Quote:

Originally Posted by maheshn0205 (Post 6146509)
I have attached the image of the output

Again, this image shows the output of what? Not JJJCR's suggestion, because JJJCR's output would contain the word "grep".

As syg00 commented, you don't have to treat smaller (GB) and bigger (TB) drives separately. Just use parted's "100%".

berndbausch 07-17-2020 09:49 PM

This part in your script creates the problem:
Code:

grep -i 'disk /dev/sd*' | grep ${i}
When $i is /dev/sdab, it generates a single line, as intended.
When $i is /dev/sda, it returns many lines, for disks named sda, sdaa, sdab, sdac and so on. Which is not your intention.

There is no need for a lot of code. Your script can be simplified radically.

JJJCR 07-19-2020 09:41 PM

Berndbausch is right, OP is grepping a wildcard.

Try this but it's not tested, hopefully you will have an idea if it doesn't work.

Quote:

grep -i 'disk /dev/sd[(a|b)]{1}' | grep ${i}
or

Quote:

Quote:

grep -E 'disk /dev/sd[(a|b)]{1}' | grep ${i}

So, basically the aim is to grep a single "a" or single "b".

Good luck~!

maheshn0205 07-20-2020 01:28 PM

Quote:

Originally Posted by JJJCR (Post 6147161)
Berndbausch is right, OP is grepping a wildcard.

Try this but it's not tested, hopefully you will have an idea if it doesn't work.



or



So, basically the aim is to grep a single "a" or single "b".

Good luck~!

Thank you JJJCR. I did tried this, when i used grep -E 'disk /dev/sd[(a|b)]{1}' | grep ${i}, it is grepping only 38 drives instead of 62.

for i in $(fdisk -l | grep -Ei 'disk /dev/sd[(a|b)]{1}' | awk '{print $2}'| sed 's/://' | sort);
do
#disk_size=$(fdisk -l | grep 'Disk /dev/sd*' | grep ${i} | awk '{print $3}')
disk_capacity=$(fdisk -l | grep -Ei 'disk /dev/sd[(a|b)]{1}' | grep ${i} | awk '{print $4}' | sed 's/,//')
case $disk_capacity in
TiB)
parted -s ${i} mklabel gpt
parted -s ${i} -a min mkpart primary xfs 0 100%
;;
GiB)
parted -s ${i} mklabel msdos
parted -s ${i} -a min mkpart primary xfs 0 100%
;;
*)
echo -n "Check the Disk partition"
;;
esac
done

This is returning me only 38 drives list and it is not partitioning the firt two drives /dev/sda, /dev/sdb.

Thanks!

berndbausch 07-20-2020 01:58 PM

fdisk output is hard to parse, leading to an overly complex program. Instead of fdisk, use /sys/block to generate a list of disks. Instead of computing disk sizes, use percentages in the parted commands.

EDIT: I just noticed you do the latter now. Good! But you don't need the capacity anymore and can you remove the case.


All times are GMT -5. The time now is 08:13 PM.