10

I am attempting to create a bash script which will create a new partition with a file system on a disk with existing partition(s).

It looks like it's easy to create partitions programmatically with parted, however it requires you to know where to start and stop the new partition, and this is where I am having trouble.

I don't want to rely on the disk having partitions in particular position/size. That is, I want to create a new partition starting immediately after the last existing one. I want to be able to then create the partition either of a fixed size, or to fill remaining space.

In Bash, is there a reliable way of determining

a) the end position of the last partition, and
b) the remaining unpartitioned space after the last partition?

3
  • 1
    Even if you can do it, I wouldn't. Imagine the kind of damage a typo can do here...
    – Joseph R.
    Sep 25, 2013 at 7:47
  • Better don't. Installers of some distributions have repartitioners and it's not really a simple task to write one. Too many corner cases, too many things you can mess up. Don't do it. If you do, let it produce suggested configuration, that has to be approved by the operator.
    – peterph
    Sep 25, 2013 at 11:15
  • I agree this is dangerous. However this is a script which will start by erasing all partitions on the disk, so messing up the partitions afterwards is no big deal. The only risk is that the user specifies the wrong disk, which is just as easy with any partition tool.
    – Alex
    Sep 25, 2013 at 23:06

2 Answers 2

4

parted can print free space. Example (I chose a complicated one on purpose):

# parted /dev/sda unit s print free
[...]
Number  Start      End        Size       Type      File system  Flags
        63s        2047s      1985s                Free Space
 1      2048s      4196351s   4194304s   primary   fat32        lba
        4196352s   4198399s   2048s                Free Space
 2      4198400s   6295551s   2097152s   primary   ext2         boot
        6295552s   6297599s   2048s                Free Space
 3      6297600s   27269119s  20971520s  primary   ext2
        27269120s  27271167s  2048s                Free Space
 4      27271168s  31115263s  3844096s   extended               lba
 5      27273216s  29192191s  1918976s   logical   ext2
 6      29194240s  31115263s  1921024s   logical   ext2
        31115264s  31116287s  1024s                Free Space

As you can see this gives you directly the position and size of the partition you may be able to create, i.e. the very last line that says Free Space. You could create a partition that starts at 31115264s and ends at 31116287s.

If it weren't for the pitfall that the extended partition isn't large enough!

But maybe you already use GPT where you do not suffer from such complications.

Grabbing the numbers should be easy enough.

function make_partition
{
    parted -s "$1" unit s mkpart primary "$2" "$3"
}

make_partition /dev/sda `parted /dev/sda unit s print free | grep 'Free Space' | tail -n 1`

Or something similar. (Naturally you'd want to do some more sanity checks here.)

@swisscheese made a good comment in the other answer, I didn't know parted offered parse friendly output. You might opt to use that instead. Example for grabbing the last largest free:

# parted -m /dev/sda unit s print free | grep 'free;' | sort -t : -k 4n -k 2n | tail -n 1
1:27269120s:27271167s:2048s:free;

Whether that's applicable for your situation (in my example, you couldn't create a partition there either, it's already full really) is something you have to figure out for yourself. :)

1
  • Thanks! For reference, I used your make_partition function but with slightly different arguments: make_partition $disk parted -m $disk unit s print free | grep "free;" | tail -n 1 | awk -F':' '{print $2 " " $3}'
    – Alex
    Sep 26, 2013 at 4:29
-1

It's easy, mkparted has a --list option, you need to use awk and --list to retrieve the last partition and then use mkpart part-type [fs-type] start end,

But your answer:

At first you should get all of partitions and with :

mystartgroup=`parted --list |awk {'print $2'}`
myendgroup=`parted --list |awk {'print $3'}`

Notes:

  1. You should convert GB to MG.
  2. You should use last value of each variable
  3. You should use -s in your parted command in final script.

If I have time, complete this script sorry for don't have time.

7
  • Hi, have you actually run the command sequences you suggest? I don't think they do what you expect them to do.. :( Sep 25, 2013 at 8:18
  • i updated , please reread . Sep 25, 2013 at 9:08
  • option 2 was changed too. Sep 25, 2013 at 9:08
  • 2
    Hi, what I meant was, 'parted --list|awk '{print $2}' is just blindly piping to awk! It does NOT get what you want. You should use the -m option to parted, which offers "parse-friendly" output. Sep 25, 2013 at 10:29
  • 1
    Nothing more to say, best of luck. Sep 25, 2013 at 10:41

Your Answer

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

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