确定块设备的大小

lfa*_*one 158 linux size

如何找出块设备的大小,例如/dev/sda?跑步ls -l没有提供任何有用的信息。

小智 191

blockdev --getsize64 /dev/sda 以字节为单位返回大小。

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

已弃用:blockdev --getsize /dev/sda以扇区为单位返回大小。

blockdevutil-linux 的一部分。

  • @heinrich5991 你别无选择。普通用户无法直接访问块设备(“原始读取”它),这有利于安全。 (9认同)
  • 不幸的是需要超级用户的权力 (4认同)
  • @heinrich5991 在使用文件系统时,您应该询问 statfs() 和朋友。更重要的是,您不应该*假设块设备大小与文件系统上的总/可用/有效/可用/任何空间之间有任何直接关系。 (2认同)
  • https://linux.die.net/man/8/blockdev 上的联机帮助页说`--getsize` 已被弃用,并建议使用`--getsz` 以获得一致的 512 字节扇区。如果必须使用`--getsize`,我想也应该使用`--getss` 来确保扇区大小符合您的预期。 (2认同)
  • 如果用户对磁盘设备节点具有读取权限,则似乎 `blockdev --getsize*`(以及可能的底层 BLKGETSIZE64 ioctl)不需要超级用户权限:``` # sudo -u user id uid=314( user) gid=4000(eng) groups=4000(eng) # ls -l hdw1 brw-rw---- 1 个用户磁盘 8, 177 Apr 10 17:17 hdw1 # sudo -u user blockdev --getsize64 hdw1 983040 # ls -l $(which blockdev) # no setuid bit -rwxr-xr-x 2 root root 26752 Dec 31 1999 /sbin/blockdev ``` (2认同)

eph*_*ent 79

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 斯达
   8 1 514079 sda1
   8 2 155774272 sda2
   8 48 1465138584 SD
   8 49 514079 SD1
   8 50 1464621952 sdd2

  • 此处报告的值是 1KiB 的倍数,这可能是一个扇区(512 字节)太小。 (3认同)
  • 并且也只报告“本地”名称。在具有 iSCSI 和/或多路径和/或 LVM 的服务器上,您会获得大量 sd* 和 dm-* 设备,但通常您需要查找您真正感兴趣的那个的符号链接(例如 /dev/映射器/* 一个) (2认同)
  • 这对我很有用。我最终做了`awk'/sd[az]$/{printf "%s %8.2f GiB\n", $NF, $(NF-1) / 1024 / 1024}' /proc/partitions` (2认同)

小智 40

cat /sys/class/block/sda/size
Run Code Online (Sandbox Code Playgroud)

这为您提供了 512 字节块的大小。

  • @heinrich5991 你怎么能确定设备块大小是*总是* 512字节? (11认同)
  • 根据 [来源](https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/include/linux/types.h?id=),扇区大小始终为 512 字节v4.4-rc6#n121)。对于未来,我正在努力让 [这个接口记录在案](https://lkml.kernel.org/r/1451154995-4686-1-git-send-email-peter@lekensteyn.nl)。 (7认同)

小智 36

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

#include <linux/fs.h>
...
ioctl(file, BLKGETSIZE64, &file_size_in_bytes);
Run Code Online (Sandbox Code Playgroud)

  • @JCCyC:`BLKGETSIZE64` 以字节为单位返回大小。请参阅`linux/fs.h`,其中注明“以字节为单位返回设备大小”。请注意,`BLKGETSIZE`(没有“64”)返回它“/512”。 (10认同)

Wad*_* M. 20

怎么样:

fdisk -l
Run Code Online (Sandbox Code Playgroud)

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

  • 用 sudo 试试,否则它什么也不打印。 (3认同)

ant*_*nio 15

互动使用

lsblk -no SIZE /dev/block-device
Run Code Online (Sandbox Code Playgroud)

请注意,如果有分区,您会得到一个列表,其中包含设备的总大小和每个分区的大小,或者您可以将分区附加到设备名称。

脚本编写

如果需要将大小存储在变量中,请使用:

size=$(lsblk -bno SIZE /dev/path | head -1)
Run Code Online (Sandbox Code Playgroud)

现在,结果总是以字节为单位,如果path不包括分区,则为总磁盘大小,否则为分区大小。

  • @MestreLion:鉴于您的想法,我更新了答案 (2认同)

Vi.*_*Vi. 11

blockdev --getsize /dev/sda


小智 9

echo "`cat /sys/class/block/sda2/size`*512" | bc
Run Code Online (Sandbox Code Playgroud)

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

echo "$((512*$(cat /sys/class/block/sda2/size)))"
Run Code Online (Sandbox Code Playgroud)

以字节为单位给出大小。

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

echo "$((512*$(</sys/class/block/sda2/size)))"
Run Code Online (Sandbox Code Playgroud)


小智 5

blockdev(8) 有不同的答案?options--getsz和 deprecated--getsize是不一样的。

  • BLKSSZGET ( blockdev --getss) 用于物理扇区大小和
  • BLKBSZGET ( blockdev --getbsz) 用于逻辑扇区大小。
echo $(($(blockdev --getsize64 /dev/sda)/$(blockdev --getss /dev/sda)))
Run Code Online (Sandbox Code Playgroud)

  • 好吧,我意识到 Linux 内核源代码中的 [`block/ioctl.c`](http://lxr.free-electrons.com/source/block/ioctl.c) 包含误导性注释。BLKPBSZGET(注意 P)获取物理扇区大小,BLKSSZGET 获取逻辑扇区大小,BLKBSZGET(或 `block/compat_ioctl.c` 中的 BLKBSZGET_32)获取文件系统分配单元(集群)大小。[使用高级格式 512e 时,逻辑和物理扇区大小不同。](http://www.oeey.com/2014/10/invalid-argument-directio-4kn.html) ([512e @ WP](http://www.oeey.com/2014/10/invalid-argument-directio-4kn.html) /en.wikipedia.org/wiki/Advanced_Format#512e)) (2认同)

小智 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.
Run Code Online (Sandbox Code Playgroud)


bab*_*bou 5

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

尽管如此,我的经验是,这些答案中的大多数都有些不完整,至少在涉及 CD 和 DVD 的情况下,特别是关于它们是否可供普通用户使用而不是仅限于超级用户。
这是基于我的 Linux Mageia 2 上的测试。

供超级用户使用的命令始终可以被普通用户访问,方法是在它们前面加上/sbin/,或者有时加上 /usr/sbin/。现在它们可能适用于普通用户,也可能不适用。

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

例如,/sbin/fdisk -l /dev/cdrom将在我的系统上工作并在驱动器中提供 DVD 的“几何形状”......这显然是无稽之谈。但它确实以字节和扇区为单位给出了 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
...
Run Code Online (Sandbox Code Playgroud)

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

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

$ cat /sys/class/block/sr0/size
10651008
Run Code Online (Sandbox Code Playgroud)

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

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

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


Pre*_*raj 5

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

blockdev --getbsz partition
Run Code Online (Sandbox Code Playgroud)

例子

# blockdev --getbsz /dev/sda1 
4096
Run Code Online (Sandbox Code Playgroud)

所以这个文件系统的块大小是4kB。

类比:板条箱中的瓶子数量。
在此输入图像描述