Is there any way to create and format a partition using a bash script?
I think it can be done with fdisk but I don't know how to feed commands from the bash script into the fdisk shell then exit the fdisk shell.
I'm wanting to create a partition then format it to ntfs from within bash.
011 Answers
Similar to the previous suggestions, piping commands to fidsk, I've found this approach useful to leave details for subsequent maintainers. The sed bits strip off all the comments before fdisk gets the input.
# to create the partitions programatically (rather than manually)
# we're going to simulate the manual input to fdisk
# The sed script strips off all the comments so that we can
# document what we're doing in-line with the actual commands
# Note that a blank line (commented as "defualt" will send a empty
# line terminated with a newline to take the fdisk default.
sed -e 's/\s*\([\+0-9a-zA-Z]*\).*/\1/' << EOF | fdisk ${TGTDEV} o # clear the in memory partition table n # new partition p # primary partition 1 # partition number 1 # default - start at beginning of disk +100M # 100 MB boot parttion n # new partition p # primary partition 2 # partion number 2 # default, start immediately after preceding partition # default, extend partition to end of disk a # make a partition bootable 1 # bootable partition is partition 1 -- /dev/sda1 p # print the in-memory partition table w # write the partition table q # and we're done
EOF 7 sfdisk
sfdisk is a Scripted version of fdisk
It is part of util-linux, just like fdisk, so availability should be the same.
A partition table with a single partition that takes the whole disk can be created with:
echo 'type=83' | sudo sfdisk /dev/sdXand more complex partition tables are explained below.
To generate an example script, get the setup of one of your disks:
sudo sfdisk -d /dev/sda > sda.sfdiskSample output on my Lenovo T430 Windows 7 / Ubuntu dual boot:
label: dos
label-id: 0x7ddcbf7d
device: /dev/sda
unit: sectors
/dev/sda1 : start= 2048, size= 3072000, type=7, bootable
/dev/sda2 : start= 3074048, size= 195430105, type=7
/dev/sda3 : start= 948099072, size= 28672000, type=7
/dev/sda4 : start= 198504446, size= 749594626, type=5
/dev/sda5 : start= 198504448, size= 618891264, type=83
/dev/sda6 : start= 940277760, size= 7821312, type=82
/dev/sda7 : start= 817397760, size= 61437952, type=83
/dev/sda8 : start= 878837760, size= 61437500, type=83Once you have the script saved to a file, you can apply it to sdX with:
sudo sfdisk /dev/sdX < sda.sfdiskFor sfdisk input, you can just omit the device names, and use lines of type:
start= 2048, size= 3072000, type=7, bootableThey are just ignored if present, and the device name is taken from the command line argument.
Some explanations:
- header lines: all optional:
partition lines:
start: offset inside the disk at which the partition starts.starthas very good defaults, and can often be ommited:- on the first line,
startis 2048, i.e. 1Mb (2048 + 512), which is a sane default for disk compatibility - further
startdefault to the first unallocated position
- on the first line,
size:man sfdisksays:The default value of size indicates "as much as possible". So to fill the disk with a single partition use:/dev/sda : start=2048, type=83type: magic byte stored on the boot sector for each partition entry. Possible values: On this example we observe:7(sda1,2and3): filesystems that Windows supports. Preinstalled Windows stuff and Lenovo recovery partitions.sudo blkidlabels help identify them.5(sda4): extended primary partition, which will contain other logical partitions (because we can only have 4 primary partitions with MBR)83(sda5,7, and8): partitions which Linux supports. For me onehome, and two roots with different Ubuntu versions82(sd6): swap
fdisk can also read sfdisk scripts with the I command, which "sources" them during an interactive fdisk session, allowing you further customization before writing the partition.
Tested on Ubuntu 16.04, sfdisk 2.27.1.
Format and populate the partitions an image file without sudo
This is a good way to learn to use sfdisk without blowing up your hard disks:
fdisk reads from stdin so you just need to feed it the appropriate commands. For example, the following clears the partition table, if there is one, and makes a new one that has a single partition that is the; entire disk:
(
echo o # Create a new empty DOS partition table
echo n # Add a new partition
echo p # Primary partition
echo 1 # Partition number
echo # First sector (Accept default: 1)
echo # Last sector (Accept default: varies)
echo w # Write changes
) | sudo fdiskI recommend you do the task you want, recording what you type so you can reproduce it.
6You can do it with just a couple of commands, use intros \n instead of multiple echos.
echo -e "o\nn\np\n1\n\n\nw" | fdisk /dev/sda 8 Create a new disklabel type gpt:
sudo /sbin/parted /dev/xvdf mklabel gpt --script
Partition the disk:
sudo /sbin/parted /dev/xvdf mkpart primary 0% 100% --script
You can script fdisk.
(echo n; echo p; echo 1; echo 1; echo 200; echo w) | fdisk /dev/sdcThat creates a 200 MB partition on /dev/sdc
Piping commands to fdisk works well as explained by other people, but this way a bit more elegant and readable:
fdisk /dev/sdc <<EOF
n
p
1
w
EOFPiping from a (temporary) file also works:
fdisk /dev/sdc < /tmp/fdisk.cmds 1 printf 'o\nn\np\n1\n\n\nw' | fdisk /dev/sda 2 The script uses fdisk to create partitons based on other people answers.
Change the following in the script:
NUM_PARTITIONS=5
PARTITION_SIZE="+10G"
Example usage is given after the script.
#!/bin/bash
if [ $# -eq 0 ]
then echo "input the device" exit
fi
NUM_PARTITIONS=5
PARTITION_SIZE="+10G"
SED_STRING="o"
TAIL="p
w
q
"
NEW_LINE="
"
LETTER_n="n"
EXTENDED_PART_NUM=4
TGTDEV=$1
SED_STRING="$SED_STRING$NEW_LINE"
for i in $(seq $NUM_PARTITIONS)
do if [ $i -lt $EXTENDED_PART_NUM ] then SED_STRING="$SED_STRING$LETTER_n$NEW_LINE$NEW_LINE$NEW_LINE$NEW_LINE$PARTITION_SIZE$NEW_LINE" fi if [ $i -eq $EXTENDED_PART_NUM ] then SED_STRING="$SED_STRING$LETTER_n$NEW_LINE$NEW_LINE$NEW_LINE$NEW_LINE" SED_STRING="$SED_STRING$LETTER_n$NEW_LINE$NEW_LINE$PARTITION_SIZE$NEW_LINE" fi if [ $i -gt $EXTENDED_PART_NUM ] then SED_STRING="$SED_STRING$LETTER_n$NEW_LINE$NEW_LINE$PARTITION_SIZE$NEW_LINE" fi
done
SED_STRING="$SED_STRING$TAIL"
sed -e 's/\s*\([\+0-9a-zA-Z]*\).*/\1/' << EOF | fdisk ${TGTDEV} $SED_STRING
EOFrun with:
sudo sh mk_partition.sh /dev/sdxxx
Not that anyone's asking but I thought I will just share it here since I bumped into it. I tried applying the following sfdisk command on Centos 7:
echo 'type=83' | sudo sfdisk /dev/xvdb
But received the following response:
Checking that no-one is using this disk right now ...
OK
Disk /dev/xvdb: 1958 cylinders, 255 heads, 63 sectors/track
sfdisk: /dev/xvdb: unrecognized partition table type
Old situation:
sfdisk: No partitions found
sfdisk: trailing junk after number
sfdisk: bad inputFinally this is what worked for me:
sfdisk -f -uS -D /dev/xvdb << EOF
2048,,83,*
EOF #!/bin/sh
hdd="/dev/hda /dev/hdb /dev/hdc"
for i in $hdd;do
echo "n
p
1
w
"|fdisk $i;mkfs.ext3 "$i1";done You can use this script. Just make sure you define your own partitions where hdd is defined. There are 2 blank spaces between 1 and w; they need to be there for taking default values.