首页 > 代码库 > OSX: diskutil命令-转换成自由空间并再对其分区
OSX: diskutil命令-转换成自由空间并再对其分区
声明:本文涉及的操作很可能会破坏你的系统文件,造成数据丢失,请慎重模仿,一切后果作者均不承担任何责任。
目的:
虽然说比较熟悉diskutil命令和它的GUI前端程序磁盘工具(Disk Utility),因为有时需要对磁盘分区进行操作,那么在前端使用磁盘工具比较方便,而且不容易出错。可是有时需要远程或者通过诸如ssh来处理,特别是对多个机器同时操作的情况下,总不能显得自己那么的笨手笨脚的吧。每个公司甚至是每个办公室,总有那么一个人难对付,那老兄要求帮忙,顺便给你来一句:要是给我管理员权限,这个我在家经常做。他不就是觉得自己牛逼嘛,你会的他也会,看不起咱么。如果不让他领教一下厉害,就让他抓住把柄了还!再说,只能通过GUI来做的,恨不得是个年轻人都会不是,年轻的时候谁没有玩过电脑啊。所以,掌握独门之计,不被常人所知的技艺,让他都不知道怎么做到的,他才能服。不用多,来个两次,他就不炸刺儿了,你也就立住脚了。
那都是题外话,那些也不是咱摆弄机器的动力。这次就是想使用命令行diskutil命令来完成两个工作:
一是把一个没用的分区,转化为没有被使用的空闲的空间。在磁盘工具中就是点-号来删除一个分区。
二是把磁盘上一个空闲空间,分配出一个分区。在磁盘工具中就是点+号来生成一个分区。
而且,一个原则是,不能破坏其他分区和里面的数据。
概况:
既然是要使用diskutil命令,就来看看它能干什么。下面列出的功能只限于本篇有用和相关的几个。
diskutil命令支持的功能:
对磁盘的操作:
- eraseDisk:擦除整个磁盘
- partitionDisk:给一个磁盘分区
对分区的操作:
- eraseVolume:擦除一个分区/卷
- reformat:给一个分区重新格式化
- resizeVolume:改变一个分区的大小
- splitPartition:把一个分区分成多个小分区
- mergePartitions:把多个分区合并
一些常识:
整理一下他的基本常识概念。
1. OS X系统内置支持的分区类型,可以用命令来列出,做到心中有数:
$ diskutil listFilesystems Formattable file systems These file system personalities can be used for erasing and partitioning. When specifying a personality as a parameter to a verb, case is not considered. Certain common aliases (also case-insensitive) are listed below as well. ------------------------------------------------------------------------------- PERSONALITY USER VISIBLE NAME ------------------------------------------------------------------------------- ExFAT ExFAT Free Space Free Space (or) free MS-DOS MS-DOS (FAT) MS-DOS FAT12 MS-DOS (FAT12) MS-DOS FAT16 MS-DOS (FAT16) MS-DOS FAT32 MS-DOS (FAT32) (or) fat32 HFS+ Mac OS Extended Case-sensitive HFS+ Mac OS Extended (Case-sensitive) (or) hfsx Case-sensitive Journaled HFS+ Mac OS Extended (Case-sensitive, Journaled) (or) jhfsx Journaled HFS+ Mac OS Extended (Journaled) (or) jhfs+它说了,个性化的名称是大小写不敏感的。
使用也是简单明了,比如jhfs+或者JHFS+或者“Journaled HFS+”都是一样的。也可以使用人可识别的名称,例如%Applie_HFS%,但是这些名称必须是系统可识别的。具体有哪些,还不清楚。还有一种使用UUID的方式就是指定分区类型的UUID, 这个UUID可以是GPT定义好的,或者是任意的,这个方式比较灵活。
因为只有Apple HFS的分区才支持无损的变更分区大小的操作,所以后面都使用JHFS+。
2. 描述分区的三个参数:Format(格式) Name(名称) Size(大小)。它们被叫做分区三联式(Triplet)。
三联式中的每个部分都使用空格分开。其中,格式在前面已经说了;名称很明显,就是字符串,可以用“”来说明;大小可以是下面的几种形式:
- 浮点数后跟B,K(10^3)),M(10^6)),G(10^9),T(10^12),P(10^15),E(10^18)等(单位是字节Byte),用来表述xxMB/GB/TB的空间大小
- 浮点数后跟S(512字节区块),Ki(2^10)),Mi(2^20)),Gi(2^30),Ti(2^40),Pi(2^50),Ei(2^60)等(单位是字节Byte),用来表述xxMB/GB/TB的空间大小
- DBS是指使用设备内定的区块大小,一般是512字节,不过要根据设备而定,所以不常用。
- 浮点数后跟%,用来表述占用磁盘空间的百分比
- R,是说所有剩余空间。在多个分区三联式中,它不一定非得是最后一个,但只能有一个(It need not be in the last triplet. It must only appear in at most one triplet among all triplets.)。
3. 我们常用的命令:
查看当前磁盘分区情况: diskutil list
查看某一个分区的具体信息:diskutil info disk1s2
4. 设备: 可以是四种形式,每种形式根据命令的需求不同,适用于不同的情况。
- 设备描述符(device identifier): 看上去类似disk1s3
- 设备节点(device node): 看上去是/dev/disk1s3
- 分区加载点(Volume mount point):默认的类似于 /Volumes/My_Partition
- UUID(通用唯一标识符): 看上去类似11111111-2222-3333-4444-555555555555
工作环境:
使用任何一个U盘进行尝试,例子中用的是1GB的U盘. 来做三个分区一个空闲空间,第一个是25%空间的exFAT分区DOS,后面是300MiB的空闲空间,然后是100MB的JHFS+分区A,最后是所有剩余空间分配指JHFS+分区B.
$ diskutil partitionDisk disk1 GPT exFAT DOS 25% free whatIam 300Mi JHFS+ A 100M JHFS+ B R Started partitioning on disk1 Unmounting disk Creating the partition map Waiting for the disks to reappear Formatting disk1s1 as ExFAT with name DOS Volume name : DOS Partition offset : 2048 sectors (1048576 bytes) Volume size : 507904 sectors (260046848 bytes) Bytes per sector : 512 Bytes per cluster: 4096 FAT offset : 128 sectors (65536 bytes) # FAT sectors : 512 Number of FATs : 1 Cluster offset : 640 sectors (327680 bytes) # Clusters : 63408 Volume Serial # : 53c9fdc4 Bitmap start : 2 Bitmap file size : 7926 Upcase start : 4 Upcase file size : 5836 Root start : 6 Mounting disk Formatting disk1s2 as Mac OS Extended (Journaled) with name A Initialized /dev/rdisk1s2 as a 95 MB HFS Plus volume with a 512k journal Mounting disk Formatting disk1s3 as Mac OS Extended (Journaled) with name B Initialized /dev/rdisk1s3 as a 349 MB HFS Plus volume with a 8192k journal Mounting disk Finished partitioning on disk1 /dev/disk1 #: TYPE NAME SIZE IDENTIFIER 0: GUID_partition_scheme *1.0 GB disk1 1: Microsoft Basic Data DOS 260.0 MB disk1s1 2: Apple_HFS A 100.0 MB disk1s2 3: Apple_HFS B 366.0 MB disk1s3
尝试1:
能否用resizeVolume把一个分区的大小变成0来达到使之变成空闲空间呢?
咱们先来复制一个文件到分区A中,在来尝试下面命令:
$ diskutil resizeVolume disk1s3 0B Started partitioning on disk1s3 A Verifying the disk Checking file system Checking Journaled HFS Plus volume Checking extents overflow file Checking catalog file Checking multi-linked files Checking catalog hierarchy Checking extended attributes file Checking volume bitmap Checking volume information The volume A appears to be OK Resizing Finished partitioning on disk1s3 A /dev/disk1 #: TYPE NAME SIZE IDENTIFIER 0: GUID_partition_scheme *1.0 GB disk1 1: Microsoft Basic Data DOS 260.0 MB disk1s1 2: Apple_HFS A 100.0 MB disk1s2 3: Apple_HFS B 366.0 MB disk1s3
可以看到,根本没有作用。其实前面已经说了resizeVolume是一种非破坏性的操作。
操作1:
好了,前面卖了个官司,其实使用这个命令就好了,特别简单。
$ diskutil eraseVolume free NONE disk1s3 Started erase on disk1s2 Unmounting disk Error: 2: POSIX reports: No such file or directory
虽然看上去有个错误,那是因为自由空间无法被装载,所以没有问题。
操作2:
现在来看看如何把空闲空间费配称一个可用的分区。
一种方法最简单,如果磁盘上的数据都不需要了,那么重新分区(diskutil partitionDisk)最最简单直接。
可是如果要保存数据呢?而经过上面的分析,你可以看到,空闲空间不会被分配一个设备,也就是没有UUID, 没有设备描述符,没有节点,没有加载点。什么都没有,就没有直接打方式。
不过可以“曲线救国”,利用resizeVolume再splitPartition来达到目的。比如把上图中A分区后面的分配回给B,可以这样做:
#resizeVolume limits -> get Current Size newVol="B" currentSize=`diskutil resizeVolume disk1s2 limits | grep "Current" | awk '{print $3$4}'` currentVol=`diskutil list disk1 |grep "disk1s2" | awk '{print $3}'` #resizeVolume to Rest: diskutil resizeVolume disk1s2 R #splitePartition: diskutil splitPartition disk1s2 2 JHFS+ $currentVol $currentSize JHFS+ $newVol R
GPT分区:
使用Diskutil list查看磁盘分区状况,并不能反应出空闲空间的状况,所以需要使用另外一个命令来解释:
$ sudo gpt -r show disk1 Password: start size index contents 0 1 PMBR 1 1 Pri GPT header 2 32 Pri GPT table 34 2014 2048 507904 1 GPT part - EBD0A0A2-B9E5-4433-87C0-68B6B72699C7 509952 612624 1122576 195312 2 GPT part - 48465300-0000-11AA-AA11-00306543ECAC 1317888 714784 3 GPT part - 48465300-0000-11AA-AA11-00306543ECAC 2032672 2 2032674 32 Sec GPT table 2032706 1 Sec GPT header
操作3:
前面有时卖关子,因为什么呢?比如前面那个在DOS分区后和A分区前的那部分空闲空间就不好办,因为前面的DOS分区不可改变分区大小,或者其他复杂状况,更是难以处理。而有了上面对GPT分区表的了解,真正可以处理的方法在这里了。
最简单的方法是:
diskutil unmountDisk force disk1 sudo gpt add disk1 diskutil unmountDisk force disk1 sudo diskutil eraseVolume JHFS+ C disk1s4 diskutil mountDisk disk1
diskutil unmountDisk force disk1 sudo gpt remove -b 1122576 disk1 sudo gpt remove -b 1317888 disk1 sudo gpt add -b 509952 -s 612624 disk1 sudo gpt add -b 1122576 -s 195312 disk1 sudo gpt add -b 1317888 -s 714784 disk1 diskutil unmountDisk force disk1 sudo diskutil eraseVolume JHFS+ C disk1s2 diskutil mountDisk disk1
Ref:
man diskutil
The Chromium Projects: Disk Format
Secrets of the GPT
GUID Partition Table