ext4のUSB外付けHDDにラベルをつける

Linux の ext4 ファイルシステムのディスクにも NTFS のボリュームラベルのようにラベル(名前)をつけられることを知った。

 cf. Linuxでストレージのラベルを確認・変更する

メインマシンの envelopes に繋がってる外付け HDD は NTFS なので、もうひとつの Ubuntu マシンである wplj の外付け HDD で試してみる。

まずはデバイスの確認。

takatoh@wplj $ lsblk
NAME   MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
sda      8:0    0 465.8G  0 disk 
├─sda1   8:1    0   512M  0 part /boot/efi
├─sda2   8:2    0 461.4G  0 part /
└─sda3   8:3    0   3.9G  0 part [SWAP]
sdb      8:16   0   2.7T  0 disk 
└─sdb1   8:17   0   2.7T  0 part /media/opabinia
sdc      8:32   0   2.7T  0 disk 
└─sdc1   8:33   0   2.7T  0 part /media/aysheaia

sdb1 と sdc1 が USB の外付け HDD だ。df コマンドに -T オプションをつけるとファイルシステムの種類を表示してくれる。

takatoh@wplj $ df -T
Filesystem     Type      1K-blocks      Used  Available Use% Mounted on
udev           devtmpfs    1948676         0    1948676   0% /dev
tmpfs          tmpfs        393812     17240     376572   5% /run
/dev/sda2      ext4      476050488  17526428  434319056   4% /
tmpfs          tmpfs       1969056       216    1968840   1% /dev/shm
tmpfs          tmpfs          5120         4       5116   1% /run/lock
tmpfs          tmpfs       1969056         0    1969056   0% /sys/fs/cgroup
/dev/sdb1      ext4     2884152984 722813244 2014810080  27% /media/opabinia
/dev/sdc1      ext4     2884152984 981135372 1756487952  36% /media/aysheaia
/dev/sda1      vfat         523248      3496     519752   1% /boot/efi
tmpfs          tmpfs        393812        52     393760   1% /run/user/1000

ext4 ファイルシステムにラベルをつけるのは e2label コマンド。
e2label デバイス名で現在のラベルを表示し、e2label デバイス名 ラベルでラベルをつける(ないしは変更する)。

takatoh@wplj $ sudo e2label /dev/sdb1

ラベルがついていないので何も返ってこない。
じゃ、つけてみよう。

takatoh@wplj $ sudo e2label /dev/sdb1 OPABINIA
takatoh@wplj $ sudo e2label /dev/sdb1
OPABINIA

ついでに /dev/sdc1 にも。

takatoh@wplj $ sudo e2label /dev/sdc1 AYSHEAIA
takatoh@wplj $ sudo e2label /dev/sdc1
AYSHEAIA

無事、ラベルがついた。
ラベルは blkid コマンドでも確認できる。

takatoh@wplj $ sudo blkid
/dev/sda1: UUID="D17D-DA22" TYPE="vfat" PARTLABEL="EFI System Partition" PARTUUID="6fa2ce8f-fa84-4c97-8280-e58107f1f5f7"
/dev/sda2: UUID="55c35560-7f0d-42ea-895c-5522c3b0a757" TYPE="ext4" PARTUUID="2e419080-c527-4316-b546-f404b2974dc6"
/dev/sda3: UUID="fe038a20-aa4e-48d9-b98c-f8932b715370" TYPE="swap" PARTUUID="8383fce1-4445-419d-a75d-1e002ac985ef"
/dev/sdb1: LABEL="OPABINIA" UUID="cd8ae5c6-3931-4855-a60b-40f27b9bc518" TYPE="ext4" PARTUUID="76dd840a-3ce4-4092-9510-a127dd9f0297"
/dev/sdc1: LABEL="AYSHEAIA" UUID="4bd2ad4c-1acf-4468-847b-1dd0a0c474a2" TYPE="ext4" PARTUUID="33288db2-8046-449d-ae4f-03f23c3864b3"

repeated_combination

Ruby の Array#repeated_combination は重複を許す組み合わせを返すメソッドだ(厳密にいうとEnumerator を返す)。
次のブログ記事で見つけた。

cf. 続:Haskell/Clojureでrepeated_combinationを実装してみる – Programmer’s Note

これを Go でやってみよう、ということで Haskell のコードを参考に作ってみた。

package main

import (
    "fmt"
)

func main() {
    xs := []int{ 1,2,3 }
    fmt.Println(repeatedCombination(xs, 3))
}

func repeatedCombination(xs []int, n int) [][]int {
    c := make([][]int, 0)
    if n == 1 {
        for _, x := range xs {
            c = append(c, []int{ x })
        }
    } else {
        for _, x := range xs {
            for _, y := range repeatedCombination(xs, n - 1) {
                c = append(c, append([]int{ x }, y...))
            }
        }
    }
    return c
}

ところが、実行結果が Array#repeated_combination と合わない。
上のコードの実行結果はこう。

^o^ > go run repeated_combination.go
[[1 1 1] [1 1 2] [1 1 3] [1 2 1] [1 2 2] [1 2 3] [1 3 1] [1 3 2] [1 3 3] [2 1 1] [2 1 2] [2 1 3] [2 2 1] [2 2 2] [2 2 3] [2 3 1] [2 3 2] [2 3 3] [3 1 1] [3 1 2] [3 1 3] [3 2 1] [3 2 2] [3 2 3] [3 3 1] [3 3 2] [3 3 3]]

対して Array#repeated_combination はこう。

irb(main):001:0> [1,2,3].repeated_combination(3).to_a
=> [[1, 1, 1], [1, 1, 2], [1, 1, 3], [1, 2, 2], [1, 2, 3], [1, 3, 3], [2, 2, 2], [2, 2, 3], [2, 3, 3], [3, 3, 3]]

順列ではなく組み合わせなので、Array#repeated_combination では例えば [1,1,2] と [1,2,1] と [2,1,1] を同じものとしているのに対して、Go のコードでは別のものとして数え上げてしまっている。
そこで改良を加えたのがこれだ。

package main

import (
    "fmt"
)

func main() {
    xs := []int{ 1,2,3 }
    fmt.Println(repeatedCombination(xs, 3))
}

func repeatedCombination(xs []int, n int) [][]int {
    c := make([][]int, 0)
    if n == 1 {
        for _, x := range xs {
            c = append(c, []int{ x })
        }
    } else {
        for _, x := range xs {
            for _, y := range repeatedCombination(xs, n - 1) {
                if x <= y[0] {
                    c = append(c, append([]int{ x }, y...))
                }
            }
        }
    }
    return c
}

実行結果。

^o^ > go run repeated_combination2.go
[[1 1 1] [1 1 2] [1 1 3] [1 2 2] [1 2 3] [1 3 3] [2 2 2] [2 2 3] [2 3 3] [3 3 3]]

今度はうまくいった。