1

I've inherited a shell script that pipes a list of 'random' characters to fdisk. What it is doing is partitioning a disk as follows:

Set up the blank disk, partition table etc Create first partition size A Create second partition, size Y, immediately after the first one. Create third partition, size X, immediately after the second one. And to add to the 'fun', A, Y, and X are calculated and may change depending on the size of the available new disk.

Fdisk will prompt for starting position based on the existing positions and the 'code' just 'hits return' and accepts this.

This code is extremely opaque and I would like to replace it with calls to 'parted --script...' instead of fdisk but I can't see that parted has a way to say 'start immediately after the last partition'. It looks like I would have to keep calculating the start position myself.

Am I correct and if so does anyone have a sensible solution for this?

1

You don't have to write an exact duplicate of everything done by a bad script. Rewriting is an opportunity to fix the logic as well as the code. Start by deciphering what the original code does and then turn it into something sane.

The answer to your direct question is "No. You'll need to provide start and end yourself'. Fortunately, that's not terribly difficult.

parted's mkpart command takes a start and and end argument (units defaults to megabytes). You just need to specify them when you create the partitions. e.g. using a disk image file:

$ cat partition.sh 
#!/bin/sh

truncate -s 1G disk.img # create a 1G disk image file

parted -s disk.img mklabel msdos    # create the partition table

# make some partitions
parted -s disk.img mkpart primary 1 100
parted -s disk.img mkpart primary 101 200
parted -s disk.img mkpart primary 201 800
parted -s disk.img mkpart primary 801 1000

parted -s disk.img print

Alternatively, running parted only once:

#!bin/sh

truncate -s 1G disk.img # create a 1G disk image file

parted -s disk.img mklabel msdos \
  mkpart primary 1 100 \
  mkpart primary 101 200 \
  mkpart primary 201 800 \
  mkpart primary 801 1000 \
  print
$ ./partition.sh 
Model:  (file)
Disk /home/cas/stack-exchange/2018-01-03/pauldsmith/disk.img: 1074MB
Sector size (logical/physical): 512B/512B
Partition Table: msdos
Disk Flags: 

Number  Start   End     Size    Type     File system  Flags
 1      1049kB  99.6MB  98.6MB  primary
 2      101MB   200MB   99.6MB  primary
 3      201MB   800MB   599MB   primary
 4      801MB   1000MB  199MB   primary

The hard part is to calculate the exact start and end values for your partitions so that they are properly aligned for the sector size. The first partition is easy - 1MB aligns with both 512 byte and 4K sectors. Any partition starting at an exact multiple of 1MB will also be aligned correctly (all of the partitions created in the example above are correctly aligned).

You can use shell variables for any of the partition start and end values, which allows you to use shell arithmetic to calculate them (but remember that shell arithmetic is integer only - use bc or dc if you need to do floating-point or percentage calculations).

BTW, you can check alignment with parted's align-check command. e.g.

$ parted disk.img align-check optimal 1
WARNING: You are not superuser.  Watch out for permissions.
1 aligned

If align-check is used with parted's -s script mode option, it doesn't produce any output. Instead, it exits with status 1 if not aligned. Otherwise it continues with the remainder of the script.

parted doesn't have any if/then capability, so if you want to automate alignment-checking as well as partition creation, use the first version of the script above so that you can insert a check-align command in between each mkpart and respond appropriately if the exit code is non-zero.

| improve this answer | |
  • BTW, as well as parted, both sfdisk (for msdos partition tables) and sgdisk (for gpt partition tables) are designed for use in scripts. They also require you to specify the start and end of each partition. – cas Feb 20 '18 at 4:29
  • Thanks - that's about where I'd got to although I have a script which can now add a partition and then figure out where the last one ended by querying parted. Probably simpler just to calculate up front as you suggest providing I can confirm that the boot sector has a fixed and known size. – Paul D Smith Feb 20 '18 at 12:56
  • First-stage bootloaders typically use only a few sectors at most after the partition table - the rule of thumb for years has been "don't touch the first 63 sectors". So, for 512-byte sector disks, almost everyone made partition 1 start at >= sector 64. Since 4K sector disks started appearing, the standard has been to start partition 1 at 1MB. It's not uncommon these days to give grub its own small type EF02 partition between sector 64 and the first 1MB, and/or a smallish type EF00 partition immediately after that or at 1MB for the EFI system partition - a few hundred MB or a GB or so. – cas Feb 20 '18 at 13:12
0

You can use parted print the end sector:

$ parted /dev/sda 'unit s print'

Number  Start     End       Size      File system  Name     Flags
 1      2048s     1048575s  1046528s  fat32        primary  boot, esp
 2      1048576s  2095103s  1046528s  ext4         primary  raid

Then the next partion starts on +1 sector after the last one: 2095103s (assuming the size of previous partition was given in correct units).

(parted) mkpart primary 2095104s 100%

Also you can use percents to leave the calculation to parted itself.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.