Skip to content

Commit 6390529

Browse files
committed
feat(cli): add option -b, -g, -z
1 parent d517289 commit 6390529

File tree

2 files changed

+109
-39
lines changed

2 files changed

+109
-39
lines changed

README.md

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ The output of lsblk.lua is modeled on [lsblk(8)](https://linux.die.net/man/8/lsb
55
lsblk.lua is implemented in [flua](https://kevans.dev/flua/), a version of Lua (currently Lua 5.4) included in the FreeBSD base system.
66

77
lsblk.lua has been tested on FreeBSD 13.4-RELEASE and 14.2-RELEASE.
8+
The ZFS functionality works on Linux and NetBSD with OpenZFS, but the focus of this project is FreeBSD.
89

910
## Requirements
1011

@@ -30,7 +31,25 @@ sudo install lsblk.lua /usr/local/bin/lsblk
3031
## Usage
3132

3233
```none
33-
usage: lsblk [-h] [-V]
34+
usage: lsblk.lua [-h] [-V] [-b] [-g] [-z]
35+
36+
List information about block devices.
37+
38+
options:
39+
-h, --help
40+
Print this help message and exit
41+
42+
-V, --version
43+
Print version number and exit
44+
45+
-b, --bytes
46+
Print sizes in bytes instead of human-readable format
47+
48+
-g, --geom
49+
Only output information about geoms of class "disk" and "part"
50+
51+
-z, --zfs
52+
Only output information about ZFS pools and datasets
3453
```
3554

3655
## Sample output

lsblk.lua

Lines changed: 89 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ local lfs = require("lfs")
55

66
local TYPE_DISK = "disk"
77
local TYPE_PART = "part"
8-
local VERSION = "0.2.0"
8+
local VERSION = "0.3.0"
99

1010
local function run_cmd(cmd)
1111
local f = io.popen(cmd .. " 2>/dev/null", "r")
@@ -182,7 +182,9 @@ local function print_item(
182182
-- `string.format` counts bytes, not Unicode characters.
183183
return "%-"
184184
.. (max_lens.name + math.max(2, #prefix))
185-
.. "s %3s%1s%-3s %6s %4s %"
185+
.. "s %3s%1s%-3s %"
186+
.. max_lens.size
187+
.. "s %4s %"
186188
.. max_lens.fstype
187189
.. "s %s"
188190
end
@@ -271,20 +273,27 @@ local function humanize_size(bytes)
271273
return s .. units[i]
272274
end
273275

274-
local function max_field_lengths(devices)
275-
local max_lens = { fstype = 0, name = 0 }
276+
local function max_field_lengths(devices, humanize)
277+
local max_lens = { fstype = 0, name = 0, size = 6 }
276278

277279
for _, device in ipairs(devices) do
278280
-- Use byte length for `string.format`.
279-
local len_name = #device.name
280-
if len_name > max_lens.name then
281-
max_lens.name = len_name
282-
end
283-
284281
local len_fstype = #device.fstype
285282
if len_fstype > max_lens.fstype then
286283
max_lens.fstype = len_fstype
287284
end
285+
286+
local size_text = humanize and humanize_size(device.size)
287+
or tostring(device.size)
288+
local len_size = #size_text
289+
if len_size > max_lens.size then
290+
max_lens.size = len_size
291+
end
292+
293+
local len_name = #device.name
294+
if len_name > max_lens.name then
295+
max_lens.name = len_name
296+
end
288297
end
289298

290299
return max_lens
@@ -349,32 +358,36 @@ local function zfs_device_info(pools, datasets)
349358
return devices
350359
end
351360

352-
local function print_tree()
353-
local geom_list = run_cmd("geom part list")
354-
local geoms = geom_parse_list(geom_list)
361+
local function print_tree(humanize, enable_geoms, enable_zfs)
362+
local devices = {}
355363

356-
local mount_list = run_cmd("mount")
357-
local mounts = parse_mount(mount_list)
364+
if enable_geoms then
365+
local geom_list = run_cmd("geom part list")
366+
local geoms = geom_parse_list(geom_list)
358367

359-
local zpool_list = run_cmd("zpool list -H -o name,size -p")
360-
local zfs_pools = parse_fields(zpool_list)
368+
local mount_list = run_cmd("mount")
369+
local mounts = parse_mount(mount_list)
361370

362-
local zfs_list = run_cmd("zfs list -H -o name,used,mountpoint -p")
363-
local zfs_datasets = parse_fields(zfs_list)
371+
local function dev_mounts(dev)
372+
return mounts[dev] or mounts["/dev/" .. dev]
373+
end
364374

365-
local function dev_mounts(dev)
366-
return mounts[dev] or mounts["/dev/" .. dev]
375+
local geom_devices = geoms_device_info(geoms, dev_mounts)
376+
table.move(geom_devices, 1, #geom_devices, #devices + 1, devices)
367377
end
368378

369-
local geom_devices = geoms_device_info(geoms, dev_mounts)
370-
local zfs_devices = zfs_device_info(zfs_pools, zfs_datasets)
379+
if enable_zfs then
380+
local zpool_list = run_cmd("zpool list -H -o name,size -p")
381+
local zfs_pools = parse_fields(zpool_list)
371382

372-
local devices = {}
373-
for _, tbl in ipairs({ geom_devices, zfs_devices }) do
374-
table.move(tbl, 1, #tbl, #devices + 1, devices)
383+
local zfs_list = run_cmd("zfs list -H -o name,used,mountpoint -p")
384+
local zfs_datasets = parse_fields(zfs_list)
385+
386+
local zfs_devices = zfs_device_info(zfs_pools, zfs_datasets)
387+
table.move(zfs_devices, 1, #zfs_devices, #devices + 1, devices)
375388
end
376389

377-
local max_lens = max_field_lengths(devices)
390+
local max_lens = max_field_lengths(devices, humanize)
378391

379392
print_item(
380393
max_lens,
@@ -395,34 +408,72 @@ local function print_tree()
395408
device.name,
396409
format_device_num(device.major),
397410
format_device_num(device.minor),
398-
humanize_size(device.size),
411+
humanize and humanize_size(device.size) or device.size,
399412
device.type,
400413
device.fstype,
401414
device.mountpoints
402415
)
403416
end
404417
end
405418

419+
local function print_help()
420+
local name = arg[0]:match("([^/]+)$")
421+
print("usage: " .. name .. " [-h] [-V] [-b] [-g] [-z]")
422+
print([[
423+
424+
List information about block devices.
425+
426+
options:
427+
-h, --help
428+
Print this help message and exit
429+
430+
-V, --version
431+
Print version number and exit
432+
433+
-b, --bytes
434+
Print sizes in bytes instead of human-readable format
435+
436+
-g, --geom
437+
Only output information about geoms of class "disk" and "part"
438+
439+
-z, --zfs
440+
Only output information about ZFS pools and datasets]])
441+
end
442+
443+
local function print_error(message)
444+
io.stderr:write(message .. "\n")
445+
end
446+
406447
local function main()
407-
if #arg == 1 then
408-
if arg[1] == "-h" or arg[1] == "--help" then
409-
local name = arg[0]:match("([^/]+)$")
410-
print("usage: " .. name .. " [-h] [-V]")
448+
local humanize = true
449+
local geom = true
450+
local zfs = true
451+
452+
for _, argument in ipairs(arg) do
453+
if argument == "-b" or argument == "--bytes" then
454+
humanize = false
455+
elseif argument == "-g" or argument == "--geom" then
456+
geom = true
457+
zfs = false
458+
elseif argument == "-h" or argument == "--help" then
459+
print_help()
411460
os.exit(0)
412-
elseif arg[1] == "-V" or arg[1] == "--version" then
461+
elseif argument == "-V" or argument == "--version" then
413462
print(VERSION)
414463
os.exit(0)
464+
elseif argument == "-z" or argument == "--zfs" then
465+
geom = false
466+
zfs = true
415467
elseif arg[1]:match("^-") then
416-
print(("lsblk: unrecognized option %q"):format(arg[1]))
468+
print_error(("lsblk: invalid option %q"):format(arg[1]))
469+
os.exit(2)
470+
else
471+
print_error("lsblk: too many arguments")
417472
os.exit(2)
418473
end
419474
end
420-
if #arg >= 1 then
421-
print("lsblk: too many arguments")
422-
os.exit(2)
423-
end
424475

425-
print_tree()
476+
print_tree(humanize, geom, zfs)
426477
end
427478

428479
main()

0 commit comments

Comments
 (0)