确定块设备的大小


Answers:


72

fdisk不了解运行Linux的Mac使用的分区布局,也不了解其他任何非PC分区格式。(是的,有mac-fdisk旧的Mac分区表和gdisk较新的GPT分区表,但这些并不是那里唯一的其他分区布局。)

由于在块设备投入使用时内核已经扫描了分区布局,所以为什么不直接询问呢?

$ cat / proc / partitions
主要次要#blocks名称

   8 16 390711384 sdb
   8 17 514079 sdb1
   8 18 390194752 sdb2
   8 32 976762584直流
   8 33 514079 sdc1
   8 34 976245952 sdc2
   8 0 156290904 sda
   8 1 514079 sda1
   8 2 155774272 sda2
   8 48 1465138584 sdd
   8 49 514079 sdd1
   8 50 1464621952 sdd2

这不适用于CD驱动器
Ganesh Sittampalam,2010年

2
并且仅报告“本机”名称。在具有iSCSI和/或多路径和/或LVM的服务器上,您会获得很多sd *和dm- *设备,但是通常您需要查找您实际感兴趣的设备的符号链接(例如/ dev / mapper / * one)
Luke404

2
此处报告的值是1KiB的倍数,可能是一个扇区(512字节)太小。
Lekensteyn

1
这对我很有用。我最终做了awk '/sd[a-z]$/{printf "%s %8.2f GiB\n", $NF, $(NF-1) / 1024 / 1024}' /proc/partitions
suprjami

173

blockdev --getsize64 /dev/sda 返回字节大小。

blockdev --getsz /dev/sda 返回512字节扇区的大小。

不推荐使用:blockdev --getsize /dev/sda返回扇区大小。

blockdev util-linux的一部分。


4
不幸的是需要超级用户的力量
heinrich5991 2012年

6
@ heinrich5991您别无选择。普通用户不能直接访问块设备(“原始读取”它),这对安全性很有帮助。
Totor

@Totor可以,但是这个特定问题的答案不需要任何超级用户权限。
heinrich5991

2
@ heinrich5991使用文件系统时,您应该询问statfs()和朋友。更重要的是,你应该承担块设备的大小和文件系统上的总/可用/有效的/自由/任何空间之间的直接关系。
Luke404

2
在手册页linux.die.net/man/8/blockdev--getsize已被弃用,并提出--getsz了一致的512字节扇区。如果--getsize必须使用,我猜--getss也应该用来确保扇区大小符合您的期望。
mwfearnley

35
cat /sys/class/block/sda/size

这样就可以以512字节的块为单位指定其大小。


9
@ heinrich5991如何确定设备块大小始终为 512字节?
Totor

5
扇区大小始终是根据512个字节的源。为了将来,我正在尝试记录此接口
Lekensteyn

谢谢你说清楚。我注意到,还有一个/ sys / class / block / sda / queue / logical_block_size。我不知道我是否应该使用,或常量512
爱德华·福尔克

33

这个简单的代码。找不到任何文档,但是很好地完成了这个窍门:

#include <linux/fs.h>
...
ioctl(file, BLKGETSIZE64, &file_size_in_bytes);

校正:它实际上使您达到SECTORS的大小。编辑它,我将投票。
JCCyC 2012年

8
@JCCyC:BLKGETSIZE64返回字节大小。请参阅linux/fs.h,其中指出“返回设备大小(以字节为单位)”。注意BLKGETSIZE(无“ 64”)返回“ / 512”。
Thanatos

我在stackoverflow.com/a/48490543/446106上部分基于此得出了更完整的示例。要在此处使用上述代码段,file必须是文件描述符(例如from open()),并且file_size_in_bytes应该是size_t
mwfearnley

(实际上,file_size_in_bytes应该是64位类型,所以应该是unsigned long long。)
mwfearnley

16

怎么样:

fdisk -l

这将为您提供所有磁盘的列表,以及它们各自的容量,使用情况等。


3
尝试使用sudo,否则它什么都不打印。
Alfe 2012年

10

blockdev --getsize /dev/sda


与一起使用sudo,否则会得到Permission denied
Wimateeka

9

lsblk 以树状视图并以人类可读的格式提供所需的信息,包括设备类型和挂载点(如果有)。

设备类型意味着它适用于CD驱动器,如Ganesh Sittampalam所要求的那样。

要仅以字节为单位获取特定设备的大小,请执行以下操作:

lsblk -rbno SIZE /dev/block-device

7
echo "`cat /sys/class/block/sda2/size`*512" | bc

或者如果您使用bash或任何其他类似POSIX的外壳,其算术运算符可使用64位整数,则您甚至无需调用 bc

echo "$((512*$(cat /sys/class/block/sda2/size)))"

以字节为单位给出大小。

到呼叫cat和叉(除了bash)可被优化掉用bashksh93zsh用:

echo "$((512*$(</sys/class/block/sda2/size)))"

5

无需在C中使用ioctl。只需查找文件的末尾并以这种方式获取大小(以字节为单位):

/* define this before any #includes when dealing with large files: */
#define _FILE_OFFSET_BITS 64
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

// ...
int fd = open("/dev/sda", O_RDONLY);
off_t size = lseek(fd, 0, SEEK_END);
// Now size is the size of the file, in bytes, or -1 on error.
// lseek(fd, 0, SEEK_SET) to get back to the start of the file.

如果要查找原始磁盘驱动器的大小,则需要root privs打开文件才能查找到结尾。
爱德华·福克

5

blockdev(8)有不同的答案吗?选项--getsz和不建议使用--getsize的不相同。

  • BLKSSZGETblockdev --getss)用于表示物理扇区大小,
  • BLKBSZGETblockdev --getbsz)用于逻辑扇区大小。
echo $(($(blockdev --getsize64 /dev/sda)/$(blockdev --getss /dev/sda)))

实际上,我认为您已经扭转了这些。(除非我的系统具有512字节的物理块和4096字节的逻辑块。)
Edward Falk 2012年

2
好吧,我意识到block/ioctl.c在Linux内核源代码中包含令人误解的注释。BLKPBSZGET(注意P)获取物理扇区大小,BLKSSZGET获取逻辑扇区大小,而BLKBSZGET(或BLKBSZGET_32 in block/compat_ioctl.c)获取文件系统分配单元(群集)大小。使用Advanced Format 512e时,逻辑和物理扇区大小会有所不同。512e @ WP
Palec 2015年

@Palec在此问题的所有答案和评论中,最有知识的评论。
Irfan Latif

5

首先,感谢所有贡献者。我学到了一些有用的东西。

不过,我的经验仍然是,大多数答案都是不完整的,至少在涉及CD和DVD的地方,特别是关于它们是否可供普通用户使用而不是仅限于超级用户使用。
这基于我的Linux Mageia 2上的测试。

普通用户始终可以通过使用前缀/sbin/,有时也使用/ usr / sbin / 来访问针对超级用户的命令。现在,它们可能对正常用户有效或无效。

即使对于普通用户,即使未安装DVD驱动器上的DVD,它们也可能会工作,而对于硬盘(即使再次以普通用户身份调用)也不会工作。

例如,/sbin/fdisk -l /dev/cdrom将在我的系统上工作,并在驱动器中给出DVD的“几何形状”……这显然是胡说八道。但是,它的确提供了DVD的大小(以字节和扇区为单位),以及正确的扇区大小(通常为2048字节)。

的情况也是如此/usr/sbin/gdisk -l /dev/cdrom,仅给出2048字节的扇区大小。

其他示例(作为非root用户,普通用户)

$ /sbin/blockdev --getss /dev/cdrom   # DVD sector size
2048
$ /sbin/blockdev --getsize64 /dev/cdrom  # DVD byte size
5453316096

$ cat /proc/partitions  # see below
...
   8        8  416027241 sda8
  11        0    5325504 sr0
   8       16 1465138584 sdb
...

这适用于DVD驱动器(此处称为)sr0,因为它的设备实际上是/dev/sr0/dev/cdrom只是与它的符号链接。大小以1k的块给出。

同样,作为普通用户,命令

$ cat /sys/class/block/sr0/size
10651008

将给出设备上DVD的大小,以/dev/sr0512字节的块为单位(以及其他磁盘的大小,即使未安装)。但是,由于cat /sys/class/block/cdrom/size/ dev / cdrom只是一个符号链接,因此不起作用

df一些人建议的命令给出了已安装分区的大小,而不是整个磁盘的大小。此外,对于已安装的CD或DVD,其容量小于CD / DVD的实际容量。更准确地说,可能有两种不同的尺寸:

  • 设备的整体大小,包括用于内部组织的大小。通常,这是使用命令将其整体复制后获得的文件的大小dd
  • 挂载时可供用户使用的空间大小(可能仅在只读模式下),总是较小。这是命令指示的大小df

$ / sbin / blockdev --getss / dev / cdrom#的DVD扇区大小
peterretief

您说的是512k,但是您的意思是只有512字节的扇区。
汤姆·黑尔

3

块是具有固定长度的一系列位或字节,即512字节,4kB,8kB,16kB,32kB等。

blockdev --getbsz partition

# blockdev --getbsz /dev/sda1 
4096

因此,此文件系统的块大小为4kB。

打个比方:板条箱中的瓶子数量。
在此处输入图片说明


这是正确的答案。
卡尔·莫里森


0

/sys/block/sda/size块大小吗?如果是这样的话?

ioctl BLKGETSIZE存在与以512为单位而不是BLKSSZGET相同的问题。BLKGETSIZE64解决了这种歧义。实际块计数 BLKGETSIZE64 / BLKSSZGET

/*BINFMTC:
http://lkml.indiana.edu/hypermail/linux/kernel/0105.2/0744.html
*/
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/fs.h>
#include <assert.h>

int main(int argc, char **argv)
{
        int fd;
        long blk=0L;
        long ssz=0L;
        long long oct=0LL;

        if((fd=open(argv[1],O_RDONLY))<0) { perror(argv[1]); exit(1); }
        if(ioctl(fd,BLKGETSIZE,&blk)<0) { perror("BLKGETSIZE"); exit(1); }
        if(ioctl(fd,BLKSSZGET,&ssz)<0) { perror("BLKSSZGET"); exit(1); }
        if(ioctl(fd,BLKGETSIZE64,&oct)<0) { perror("BLKGETSIZE64"); exit(1); }
        if(close(fd)<0) { perror("close"); exit(1); }
        printf("BLKGETSIZE=%ld BLKSSZGET=%ld BLKGETSIZE64=%lld BLKGETSIZE64/BLKSSZGET=%ld SIZEGB=%f #%f\240GiB\n\n",\
blk,ssz,oct,(long)(oct/(long long)ssz),(double)oct/1000000000.0,(double)oct/1073741824.0);

        fflush(stdout); /* before exec */

        execl("/bin/bash","bash","-c",\
"for i in \
/sys/block/?d?/{size,alignment_offset,?d??/size,?d??/alignment_offset,queue/*block*,queue/*sector*}; \
do test -f \"$i\" && echo \"$i: $(<$i)\"; done"\
,NULL);

        exit(127);
        return 127; /* not reached */
}

参见http://lkml.indiana.edu/hypermail/linux/kernel/0105.2/0744.html


1
滥用断言:如果禁用断言,则不再发生必要的副作用。
Alfe 2012年


0
echo "`blockdev --getbsz /dev/sdc`/1024"|bc

将以KB显示输出

[root@veritas datadg2]# echo "`blockdev --getbsz /dev/sdc`/1024"|bc
4
[root@veritas datadg2]#

bash可以内联进行计算:echo $(( $(blockdev ...)/1024 ))。另请注意,--getbsz给出的是块的大小,而不是设备的大小。
mwfearnley


-1
fdisk -l /dev/sda | grep -m1 ^Disk | awk '{print $3 " " $4}'

我发现它比所有这些标准工具或proc条目都非常有用


-3
df -k | grep /dev/sda

将为您提供以KB为单位的大小(第一个数字),已用空间(第二个数字)和可用空间(第三个数字)


5
只有挂载了文件系统。
lfaraone

2
这与块设备空间无关,它将为您提供恰好在/ dev / sda上的已挂载文件系统的已用和可用空间。那未分区的空间呢?如果您有多个分区怎么办?
kbyrd 2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.