それマグで!

知識はカップより、マグでゆっくり頂きます。 takuya_1stのブログ

習慣に早くから配慮した者は、 おそらく人生の実りも大きい。

LVMのlvreduce でファイルシステム(ext)を縮小する(lvresizeについても)

LVMで管理しているボリュームを縮小する。

lvm2 で管理しているLVのボリュームを縮小して、容量を開放するための手順

作業手順は次のようになります。

  1. ターゲットのLVとそのファイルシステムを確認する
  2. FSを縮小する
  3. lv を縮小する

resize2fs はlvreduceの後でも先でもいいが、ボリュームサイズの変更の前にやるほうが無難

現在のファイルシステムとボリューム名を確認しておく。

$ sudo mount /dev/mapper/sample01-lv01 mnt
$ df -h mnt
ファイルシス              サイズ  使用  残り 使用% マウント位置
/dev/mapper/sample01-lv01    60G   44M   28G    1% /home/takuya/mnt
$ sudo umount /dev/mapper/sample01-lv01

ファイルシステムをリサイズする。

今回はext4 だったので、resize2fs を掛けていく。

ファイルシステムをチェックして
$ sudo e2fsck -f  /dev/mapper/sample01-lv01
e2fsck 1.42.12 (29-Aug-2014)
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
リサイズする。

今回は60GB→30GB

takuya@:~$ sudo resize2fs /dev/mapper/sample01-lv01 30G
resize2fs 1.42.12 (29-Aug-2014)
Resizing the filesystem on /dev/mapper/sample01-lv01 to 7864320 (4k) blocks.
The filesystem on /dev/mapper/sample01-lv01 is now 7864320 (4k) blocks long.
リサイズできたのを確認

mount とかで確認

LV を縮小する

$ sudo lvreduce sample01/lv01 -L 30G
  WARNING: Reducing active logical volume to 30.00 GiB
  THIS MAY DESTROY YOUR DATA (filesystem etc.)
Do you really want to reduce lv01? [y/n]: y
  Size of logical volume sample01/lv01 changed from 60.00 GiB (15360 extents) to 30.00 GiB (7680 extents).
  Logical volume lv01 successfully resized

2022-12-15 追記 lvresize を使う

いちどに沢山の量をリサイズすると、上記の方法ではうまくいかない。

そこで、lvresize を使ったほうが早い また、処理が2回はめんどくさい。上記の手順を一度に終える次のコマンドが安全で確実、
さらに、+/- を使って増分減分を指定できるので便利。

## 縮小
sudo lvresize -v --resizefs --size -10G /dev/mapper/my-root
## 拡張
sudo lvresize -v --resizefs --size +10G /dev/mapper/my-root

まとめ

lvreduce を使うことでかんたんにボリュームの容量を変更できて、物理HDDのパーティションをいじるより圧倒的に楽ちんですね。

2023-05-02

タイポ修正

参考資料

  • man resize2fs
  • man lvreduce

LVMの lvextend でLVを拡張する

LVMで作ったLVのパーティションを拡張する。

手順としては、物理HDDのパーティションを拡張するときや、HDDを大容量に換装した時の手順とほぼ同じですね。

  1. pv の確認
  2. vg の確認
  3. lv の確認
  4. lv の容量を追加する
  5. lv の上のファイルシステムを拡張する

LVの拡張には次のコマンドが大事

sudo lvextend -l +100%FREE vg_name/lv_name

ただし、このコマンドを実行するまでに、pvに追加vgに追加が必要なので、順番に書いておきます。

pv の確認

まず、PVの状態を確認しておきます。

$ sudo pvs /dev/sdc1 
  PV         VG   Fmt  Attr PSize   PFree
  /dev/sdc1       lvm2 ---  150.00g 150.00g

実験用のvg / lv / FS を作ります。

今回は、作業手順を確認するために、VGをそのためだけに作ることにした。

vgの作成
$ sudo vgcreate sample01 /dev/sdc1
  Volume group "sample01" successfully created
lv の作成
$ sudo lvcreate -n lv01 -L 30GB sample01
  Logical volume "lv01" created
$ ls /dev/mapper
sample01-lv01
FSの作成
$ sudo mkfs.ext4 /dev/mapper/sample01-lv01
mke2fs 1.42.12 (29-Aug-2014)
Creating filesystem with 7864320 4k blocks and 1966080 inodes
Allocating group tables: done
Writing inode tables: done
Creating journal (32768 blocks): done
Writing superblocks and filesystem accounting information: done
マウントして確認しておく

30GBのファイルシステムが作られていて正しく扱えることを確認した。

$ sudo mount /dev/mapper/sample01-lv01 mnt
$ ls mnt
lost+found
$ df  mnt
ファイルシス              1K-ブロック  使用   使用可 使用% マウント位置
/dev/mapper/sample01-lv01    30832636 44992 29198396    1% /home/takuya/mnt

LV の拡張

実験用の環境が作れたので、ここから、LV を拡張してく。

最初にアンマウントしておく
$ sudo umount /dev/mapper/sample01-lv01
lvextend でLVに容量を追加する。
$ sudo lvextend -L +30GB sample01/lv01
  Size of logical volume sample01/lv01 changed from 30.00 GiB (7680 extents) to 60.00 GiB (15360 extents).
  Logical volume lv01 successfully resized

ポイントは追加したい容量を引数で指定する 。上記の例では30GBを足すので、 -L +30GB と増分を書く。

同じことをするのに、他の指定方法もある。

  • -L +30GB 増分の指定
  • -L 60GB 増加後の容量の指定
  • -l +20% 増分を%で指定。 (VGに対しての%)
  • -l 40% 増分後の容量を%で指定。  (VGに対しての%)
  • -l +100%FREE 残りの容量を全部割り振る

計算が面倒なときや大体でいいときはパーセント指定が楽だよね。あとでLVMは容量変えられるし。

使用量が変化したことを確認しておく

pvs で割当ての容量が変化して、FREEの空き容量が減ったことを確認。

$ sudo pvs /dev/sdc1 
  PV         VG       Fmt  Attr PSize   PFree
  /dev/sdc1  sample01 lvm2 a--  150.00g  90.00g

lvs で、容量が変化していることを確認。

$ sudo lvs sample01/lv01
  LV   VG       Attr       LSize  Pool Origin Data%  Meta%  Move Log Cpy%Sync Convert
  lv01 sample01 -wi-a----- 60.00g

ボリュームの容量が増加したので、これでほぼ作業は終了。あとはファイルシステムをボリュームの空き容量に合わせて拡張していく

ファイルシステムを拡張する

今回は、実験用にext4 を使ったので、ext4 の拡張手順に従って拡張する。

最初にe2fck -fでチェックしておく
$ sudo e2fsck -f  /dev/mapper/sample01-lv01
e2fsck 1.42.12 (29-Aug-2014)
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
/dev/mapper/sample01-lv01: 11/1966080 files (0.0% non-contiguous), 167409/7864320 blocks
次に resize2fs で空き容量いっぱいまで拡張する

次に、resize2fs のコマンドをオプションの容量指定無しで用い100%までファイルシステムを拡張する。

$ sudo resize2fs /dev/mapper/sample01-lv01
resize2fs 1.42.12 (29-Aug-2014)
Resizing the filesystem on /dev/mapper/sample01-lv01 to 15728640 (4k) blocks.
The filesystem on /dev/mapper/sample01-lv01 is now 15728640 (4k) blocks long.

最後にマウントして確認

$ sudo mount /dev/mapper/sample01-lv01 mnt
$ df -h mnt
ファイルシス              サイズ  使用  残り 使用% マウント位置
/dev/mapper/sample01-lv01    59G   52M   56G    1% /home/takuya/mnt

以上で拡張の手順は終わり。

物理HDDで使う時と、LVMで容量を拡張する時の、2つの大きな違いは、容量追加がとても楽なこと。

パーティションの移動や、前半部分を開けたり後方部分を開けたりといったfdisk のめんどくさい作業が要らなくなって嬉しい。

パーティションを移動するときに比べて圧倒的にかかる時間が少ないのも魅力的である。

ただ、物理ディスク内を虫食いに使ってしまうので、リカバリ時に少し苦労するかもしれない。その懸念もLVMをちゃんと使えれば防ぐことが出来る。その話はまた別のエントリで。

参考資料

  • man lvextend
  • man resiz2fs
  • man e2fsck

LVMでボリュームを切り出して使う - 使い方とメリット

LVM 出来ることを試していくシリーズ

LVMでボリュームを切り出して使う。

今回は、大きなディスクから、小さなディスクを作ってみる。

LVM的に表現すれば、VGから複数のLVを生み出す。この作業になります。

LVM でボリュームを分割する

LVM でLV(論理ボリューム)を切り出して使うことの特徴について。

/dev/sda からパーティション切出しと、似ていますが全然違います。LVMはデバイスマッパー(ディスクの仮想化みたなもの?)なので、パーティションより低レイヤになります。つまり、LVとは可変長のハードディスクだと思っていたらいいと思う。パーティションだと、並び順を意識して容量を変更していきますが、LVMでは不要です。

今回試すこと

LV から複数のLVを切り出して、その中にパーティションを作る。

PV / VG を作る

ぱぱっと実験用のLVMのVGを作っておきます。

$ sudo pvcreate /dev/sdc1
$ sudo vgcreate sample01 /dev/sdc1
$ sudo vgs
  VG       #PV #LV #SN Attr   VSize   VFree
  acid       1   3   0 wz--n- 223.57g 128.57g
  sample01   1   1   0 wz--n- 150.00g 150.00g

一つ目のLV を作成します。

一つ目は lv01 という名前で、VG の空き容量の20% を割当ててみます。

$ sudo lvcreate -n  lv01  -l 20%FREE sample01
  Logical volume "lv01" created
$ sudo lvs
  LV   VG       Attr       LSize  Pool Origin Data%  Meta%  Move Log Cpy%Sync Convert
  lv01 sample01 -wi-a----- 30.00g

二つ目のLVを作成

二つ目は、容量を30GBで指定して作成してみます。

$ sudo lvcreate -n  lv02  -L 30GB  sample01
  Logical volume "lv02" created
$ sudo lvs
  LV   VG       Attr       LSize  Pool Origin Data%  Meta%  Move Log Cpy%Sync Convert
  lv01 sample01 -wi-a----- 30.00g
  lv02 sample01 -wi-a----- 30.00g

lv01 の容量を増量します。

lvexntend を使って、容量を増加させることが出来ます。vg の空き容量から割当てられます。

$ sudo lvextend   -l +20%FREE  sample01/lv01
  Size of logical volume sample01/lv01 changed from 30.00 GiB (7679 extents) to 48.00 GiB (12287 extents).
  Logical volume lv01 successfully resized

ここの動作がディスクのパーティションを作成時との、場合と大きな違いです。

今回は20%を空き容量から割当ててパーティションに追加しました。

もしディスクのパーティションで容量を分割している場合だと、こんなに手軽に容量追加は出来ないでしょう。

ディスクパーティションを切っていた場合。

もし以下のようにパーティションを割っていた場合を考えてみましょう。

  • /dev/sdc
    • /dev/sdc1 30%
    • /dev/sdc2 30G
    • 60%未使用

パーティションを移動のために、まず /dev/sdc2 を後退させ、次に /dev/sdc1 を拡張します。さらにファイルシステムをリサイズし、終わったら確保した空き容量に/dev/sdc1を拡張する必要があります。これはパーティションファイルシステム開始位置を決めないといけないのですごく面倒です。パーティションの移動って面倒なんですよね。dd でパーティションを一旦未使用領域に移せば作業の工数的には楽です。しかし時間がもったいないです。resize2fs とfdisk でパーティションを移動もいいのですが、不便ですよね。

パーティションの場合利用容量に正比例して必要時間が増えていきます。一方でLVMを使ったLV作成・追加では時間がほぼゼロです。これがLVMのLVとVGで管理と、パーティション管理する場合の違いと言えるでしょう。

まとめ LV によるPE分割のメリット

  • /home, /var など容量の読めないものでも扱いやすい。
  • 容量が必要になっても大丈夫
  • 時間はかからない。
  • とりあえず分けておいてあとで考えられる。
  • LVは可変長サイズ・ハードディスク

また、次のようなことも出来ます。

拡張と縮小は別に書きます。

LVMの作成と削除のやり方の例-基本コマンド

基本的なLVMの作成例

  1. LVM の作成計画
  2. LVM の作成
  3. LVM の削除

作ったものは後始末するということで、LVMを作って削除するまでをメモしておきます。

用意するもの

LVM の容量計画

どのように物理的なHDDやパーティションを扱いたいのか決めておく必要がある。

ただし、LVMの知識がないとこの計画が立たないので、LVM作成を躊躇する人や、よくわからないのでフォーマットしちゃうような人が多い気がする。

でも大丈夫、LVMは「あとでどうにでもにも」することができるので、LVM管理下においちゃって大丈夫

今回は実験用にHDDのパーティションをLVM管理下においちゃうことにする。

LVM の名前

名前をつけないと、適当な名前がlvm2 のモジュールによって命名される。 今回は何か名前をつけようと思います。

作成の順番と使用

LVMで管理するディスクを決めたら、次のような手順で有効にしてファイルを書き込めるようにする。

計画→ PV 作成 → VG作成 → LV 作成 → フォーマット → マウント

PV の作成

sudo pvcreate /dev/sdc1
PV の作成結果を確認
takuya@:~$ sudo pvs
  PV         VG         Fmt  Attr PSize   PFree
  /dev/sdc1  example-vg lvm2 a--  150.00g 150.00g

VGの作成

sudo vgcreate example-vg /dev/sdc1
VG の作成結果を確認
takuya@:~$ sudo vgs
  VG         #PV #LV #SN Attr   VSize   VFree
  example-vg   1   0   0 wz--n- 150.00g 150.00g

LV の作成

sudo lvcreate -n example-lv  -l 100%FREE example-vg
LV の作成結果を確認
takuya@:~$ sudo lvs
  LV         VG         Attr       LSize   Pool Origin Data%  Meta%  Move Log Cpy%Sync Convert
  example-lv example-vg -wi-a----- 150.00g

lsblk でデバイス・マッパーが出来たのを確認

takuya@:~$ lsblk
NAME                        MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
sdc                           8:32   0 931.5G  0 disk
└─sdc1                        8:33   0   150G  0 part
  └─example--vg-example--lv 254:3    0   150G  0 lvm

フォーマット

sudo mkfs.ext4 /dev/mapper/example--vg-example--lv

マウントして書込みする。

takuya@:~$ sudo mount /dev/mapper/example--vg-example--lv mnt
takuya@:~$ cd mnt
takuya@:mnt$ sudo chmod 777 .
takuya@:mnt$ touch  a
takuya@:mnt$

コレで基本的なLVMの使い方はわかった。

lvm を使う上で一番基本になる使い方なので暗記しておいて、これらのコマンドをサラッと書ける必要がある。

つぎは、この作ったLVMを削除する

LVM の削除について

削除は、作成の逆を順番にやっていきます。

マウント解除 → LV削除 → VG 削除 → PV 削除

LV の削除

LV を削除していきます。先に削除前の状態を確認しておきます。

lvs で確認しながら、lvremove していきます。

LVの作り直しでも必要になるので覚えておく。

削除前のLV

takuya@:~$ sudo lvs
  LV         VG         Attr       LSize   Pool Origin Data%  Meta%  Move Log Cpy%Sync Convert
  example-lv example-vg -wi-a----- 150.00g

LV の削除

sudo lvremove  VgName/LvName

実際にやってみた結果

takuya@:~$ sudo lvremove  example-vg/example-lv
Do you really want to remove active logical volume example-lv? [y/n]: y
  Logical volume "example-lv" successfully removed
  Volume group "example-lv" not found
  Skipping volume group example-lv

削除後のLV

takuya@:~$ sudo lvs
  LV   VG   Attr       LSize  Pool Origin Data%  Meta%  Move Log Cpy%Sync Convert

VG の削除

VG の削除前と削除後の状態を確認しながら、VGの削除をやっていきます。

VGを削除して作り直すときにも使います。

削除前の VG

takuya@:~$ sudo vgs
  VG         #PV #LV #SN Attr   VSize   VFree
  example-vg   1   0   0 wz--n- 150.00g 150.00g

VGの削除

takuya@:~$ sudo vgremove example-vg
  Volume group "example-vg" successfully removed

削除後のVG

takuya@:~$ sudo vgs
  VG   #PV #LV #SN Attr   VSize   VFree

PEをPV からの離脱

PEに登録してPVにしたボリュームを、解除します。

PV の状態を確認

takuya@:~$ sudo pvs
  PV         VG   Fmt  Attr PSize   PFree
  /dev/sdc1       lvm2 ---  150.00g 150.00g

PEの削除

takuya@:~$ sudo pvremove /dev/sdc1
  Labels on physical volume "/dev/sdc1" successfully wiped

PVの状態を確認

takuya@:~$ sudo pvs
  PV         VG   Fmt  Attr PSize   PFree

これで、LVMを使わない状態に戻すことが出来ました。

まとめ

  • PV / VG / LV の順番に登録していく
  • LV は通常ボリュームと同じに扱える
  • pvcreate / pvmorevevgcreate /vgremovelvcreate / lvremove と対になってる
  • LV / VG / PV の順番に解除していく( 登録時の逆

2022-06-15

lvremove のVG/LVの記載がおかしかったので修正

LVM上にLVMを構成する

LVM で切り出したボリュームをLVMのPEにすることが出来る

ボリュームグループとボリュームグループを結合するのに何か手はないかなと考えていた。

ボリュームグループから切り出したボリュームを、別のボリュームグループに参加させたいなと思ったらあっけなく出来てしまったのでメモ。

LVM おさらい。

LVM には PV / VG / LV がある。

VGを変えることは出来ない。

たとえば /dev/sda をVG : myVol01 に入れちゃえば、 /dev/sda を2つに分けて使うとしても VG : myVol01 から切り出して使うことになる。

VG を別のVGに登録したい。

LVM上にLVを構成する

  • VG : myVol01から切り出した LV を PE の登録し VG: OverVG01 を構成する
  • VG : myVol02から切り出した LV を PE の登録し VG: OverVG01 を構成する

そうすると、頭がオカシイかんじだけど容量を再構成できるね

SSDの /dev/sda をLVMの構成に放り込んで VG 作ったけど、やっぱり別のVGにちょっと分けてほしいみたいなとき。

SSDから10GBのLVを切り出した

takuya@:~$ sudo lvcreate -L 10GB acid -n cc-01
  Logical volume "cc-01" created

結果を確認

takuya@:~$ sudo lvs
  LV    VG   Attr       LSize  Pool Origin Data%  Meta%  Move Log Cpy%Sync Convert
  cc-01 acid -wi-a----- 10.00g
  home  acid -wi-ao---- 50.00g
  root  acid -wi-ao---- 40.00g
  swap  acid -wi-ao----  5.00g

mapper にあることを確認

takuya@:~$ ls /dev/mapper/acid-cc--01
/dev/mapper/acid-cc--01

PEにLVMを登録する。

takuya@:~$ sudo pvcreate  /dev/mapper/acid-cc--01
  Physical volume "/dev/acid/cc-01" successfully created

やべぇ、LVMで作ったボリュームをPVに登録できちゃうぅ、らめぇ

登録の結果を確認する。

takuya@:~$ sudo pvs
  PV              VG   Fmt  Attr PSize   PFree
  /dev/acid/cc-01      lvm2 ---   10.00g  10.00g
  /dev/sdb2       acid lvm2 a--  223.57g 118.57g
  /dev/sdc1            lvm2 ---    1.00g   1.00g
  /dev/sdc2            lvm2 ---    1.00g   1.00g
  /dev/sdc3            lvm2 ---    1.00g   1.00g
takuya@:~$

次々にVGを組み立てていく

takuya@:~$ sudo pvs
  PV              VG   Fmt  Attr PSize   PFree
  /dev/acid/cc-01      lvm2 ---   10.00g  10.00g
  /dev/sdb2       acid lvm2 a--  223.57g 118.57g
  /dev/sdc1            lvm2 ---    1.00g   1.00g
  /dev/sdc2            lvm2 ---    1.00g   1.00g
  /dev/sdc3            lvm2 ---    1.00g   1.00g
takuya@:~$ sudo vgcreate MyVG_01 /dev/sdc1
  Volume group "MyVG_01" successfully created
takuya@:~$ sudo vgextend MyVG_01 /dev/sdc2
  Volume group "MyVG_01" successfully extended
takuya@:~$ sudo vgextend MyVG_01 /dev/sdc3
  Volume group "MyVG_01" successfully extended
takuya@:~$ sudo vgextend MyVG_01 /dev/acid/cc-01
  Volume group "MyVG_01" successfully extended

出来上がったVGがこちら

takuya@:~$ sudo pvs
  PV              VG      Fmt  Attr PSize    PFree
  /dev/acid/cc-01 MyVG_01 lvm2 a--    10.00g   10.00g
  /dev/sdb2       acid    lvm2 a--   223.57g  118.57g
  /dev/sdc1       MyVG_01 lvm2 a--  1020.00m 1020.00m
  /dev/sdc2       MyVG_01 lvm2 a--  1020.00m 1020.00m
  /dev/sdc3       MyVG_01 lvm2 a--  1020.00m 1020.00m

ほーらVGからVGが作れたよ。

面白いね。面白いけど何に使うんだろう。

ボリュームグループを複数束ねることとかできそうだよね。

VGとVGをくっつけて新しいVGを作るとかも出来るってことだ。

imageMagickのconvertコマンドで進捗をモニタリングする

convert コマンドが遅い時がある

PDFとJPGを扱ってると、時間がかかって後どれくらいだ?と気になることがあるので。

convert -monitor

と monitor オプションをつけると、progress をモニタリングできて便利。

実際やってみるとこんな感じ

takuya@$ convert -monitor *.jpg out.png
Load/Image//var/tmp[magick-17626kqKU0vo7Ni9l1]: 729 of 730, 100% complete
Load/Image//var/tmp[magick-17626kqKU0vo7Ni9l2]: 738 of 739, 100% complete
Load/Image//var/tmp[magick-17626kqKU0vo7Ni9l3]: 739 of 740, 100% complete
Load/Image//var/tmp[magick-17626kqKU0vo7Ni9l4]: 730 of 731, 100% complete
(snip
Load/Image//var/tmp[magick-17626kqKU0vo7Ni9l525]: 729 of 730, 100% complete
Load/Image//var/tmp[magick-17626kqKU0vo7Ni9l526]: 733 of 734, 100% complete
Load/Image//var/tmp[magick-17626kqKU0vo7Ni9l527]: 733 of 734, 100% complete
mogrify image[out-0000.jpg]: 526 of 527, 100% complete
write image[out-0000-526.png]: 526 of 527, 100% complete

すこしだけ、落ち着いて見ていられることが出来た。でも前処理が長いときは全く表示されなかったので、ちょっと不安は残る。

参考資料

  • man convert

macのfdisk コマンドでUSBメモリを初期化する。

Macfdisk コマンドを使ってUSBメモリを初期化する。

fdisk コマンドは man fdisk すればBSD manual が出てくるので、 BSD コマンドらしい。

fdisk コマンドでディスクを消去する

MBRのディスクパーティション・テーブルを初期化することで行けたっぽい

sudo fdisk -a dos  -i /dev/diskN 

もしマウントされてるならアンマウントする

sudo diskutil unmountDisk  /dev/diskN

FAT32 で初期化する。

ディスクパーティションを初期化したので、FAT32にしておく

takuya@Desktop$ sudo newfs_msdos -F32 /dev/diskN
newfs_msdos: warning: /dev/disk3 is not a character device
512 bytes per physical sector
/dev/disk3: 30001904 sectors in 1875119 FAT32 clusters (8192 bytes/cluster)
bps=512 spc=16 res=32 nft=2 mid=0xf0 spt=32 hds=255 hid=0 drv=0x00 bsec=30031250 bspf=14650 rdcl=2 infs=1 bkbs=6

これでFAT32でUSBメモリを初期化出来た。

diskutil eraseDisk の方が楽だね・・・

気になった所

GPT はどうも無理っぽいんだけどどうしようかな。

パーティション作成はどうやるんだろう。

参考

  • help 見た
$ fdisk help
usage: fdisk [-ieu] [-f mbrboot] [-c cyl -h head -s sect] [-S size] [-r] [-a style] disk
    -i: initialize disk with new MBR
    -u: update MBR code, preserve partition table
    -e: edit MBRs on disk interactively
    -f: specify non-standard MBR template
    -chs: specify disk geometry
    -S: specify disk size
    -r: read partition specs from stdin (implies -i)
    -a: auto-partition with the given style
    -d: dump partition table
    -y: don't ask any questions
    -t: test if disk is partitioned
`disk' is of the form /dev/rdisk0.
auto-partition styles:
  boothfs     8Mb boot plus HFS+ root partition (default)
  hfs         Entire disk as one HFS+ partition
  dos         Entire disk as one DOS partition
  raid        Entire disk as one 0xAC partition

macのコマンドでUSBメモリを初期化する。

mac の コマンドでUSBメモリを初期化する

diskutil を使うのが、シンプルな回答。

sudo diskutil eraseDisk FAT32 MY_NAME MBRFormat /dev/diskN

MY_NAME は自由に決められるが、FAT32の場合は「大文字」でないとエラーになった。

実際にやってみた例

takuya@Desktop$ diskutil unmountDisk  /dev/disk3
Unmount of all volumes on disk3 was successful
takuya@Desktop$ sudo diskutil eraseDisk FAT32 MY_NAME MBRFormat /dev/disk3
Started erase on disk3
Unmounting disk
Creating the partition map
Waiting for the disks to reappear
Formatting disk3s1 as MS-DOS (FAT32) with name NAME
512 bytes per physical sector
/dev/rdisk3s1: 30001904 sectors in 1875119 FAT32 clusters (8192 bytes/cluster)
bps=512 spc=16 res=32 nft=2 mid=0xf8 spt=32 hds=255 hid=2 drv=0x80 bsec=30031248 bspf=14650 rdcl=2 infs=1 bkbs=6
Mounting disk
Finished erase on disk3
takuya@Desktop$ fdisk /dev/disk3
Disk: /dev/disk3    geometry: 1869/255/63 [30031250 sectors]
Signature: 0xAA55
         Starting       Ending
 #: id  cyl  hd sec -  cyl  hd sec [     start -       size]
------------------------------------------------------------------------
 1: 0B 1023 254  63 - 1023 254  63 [         2 -   30031248] Win95 FAT-32
 2: 00    0   0   0 -    0   0   0 [         0 -          0] unused
 3: 00    0   0   0 -    0   0   0 [         0 -          0] unused
 4: 00    0   0   0 -    0   0   0 [         0 -          0] unused

disk utility.app でいいんだけど。

もちろんGUIでいいんだけど、何度もやってるといちいちウインドウでやるのが手間に思えて来てやばい。

参考資料

http://superuser.com/questions/527657/how-do-you-format-a-2-gb-sd-card-to-fat32-preferably-with-disk-utility

bashの似てて紛らわしいもの '.' と 'source' について

似てて紛らわしいものシリーズ  . / source について

bash の記号で初心者泣かせの、似てて紛らわしかったり、使い分けがわからなかったり、読み方を間違えてパニックになる記号について書く。

. / source について

.source は、どちらも同じ意味と効果を持ちます。

. / source は外部のファイルを読み込んで現在実行中の箇所に展開します。

他の言語でいうところの、requireimport になります。

大きな違い

  • .POSIX に定義されていてどこでも使えます。
  • sourcebash 特有のコマンドです。*1

そのため source コマンドは/bin/sh では使えません。と一般的に説明されてています。

sh では sourceは動きません。。。?

そのshはほんとうにshですか?

例外もあります。 たとえば、手元のmac OSX の場合。sh は bash です。。。ああ。bash互換モードだ。*2

おまえbashだったのか。

/bin/sh --version 
GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin15)
Copyright (C) 2007 Free Software Foundation, 

*3

おまえdash だったのか

takuya@:~$ ls -l /bin/sh
lrwxrwxrwx 1 root root 4 2016-06-13 22:10 /bin/sh -> dash

違いに注意しないと大変。

osx の sh は bash なので source が存在します。

debian / ubuntu で使われてる debian shell のdash の場合は POSIX性を重要視してるのでsource は存在ません。

いろいろなところで動かす場合は . を使ったほうが無難なのかもしれません。

mac の sh の場合

takuya@~$ /bin/sh
sh-3.2$ source
source: usage: source filename [arguments]
sh-3.2$

debian の sh の場合

takuya@:~$ /bin/sh
$ source
sh: 1: source: not found

どっち使えばいいの?

bashを前提にしているし、読みやすいし source でいいと思います。*4

POSIX互換を意識する方々は . でいいでしょうし、source 使う場合でもシェルに次のように書いておけば、どこでも大丈夫でしょう。

type source 2>&1 >/dev/null ||alias source=.

記号を減らして検索性や可読性を向上させる視点において source の方がいいように思います。*5

. の覚え方

個人的なことですが、. はカレントシェルにファイルを読み込むと覚えています。カレントといえば . ですからね。

takuya@~$ . ~/.bashrc

参考資料

http://askubuntu.com/questions/25488/what-is-the-difference-between-source-and-in-bash

修正

2017-01-09 段落校正
2021-06-04 タイトルがわかりにくいので修正。

*1: もちろん zsh などでも使えますが

*2: 自分で起動するときでも bash --posix で起動すると POSIX互換モードになります。

*3:patch level 57 だからShell Shockは大丈夫ですね。

*4: わたしは、bash でほとんど書いてしまうのでsourceを多用しますが。意見には個人差が有ります

*5:意見には個人差が有ります

macのrbenv でインストールにコケたのでメモ

rbenv でruby 2.3.3 を入れようとしたらエラーになった。

takuya@Desktop$ CC=/usr/bin/gcc CONFIGURE_OPTS="--with-readline-dir=/usr/local/opt/readline --with-openssl-dir=/usr/local/opt/openssl" rbenv install   2.3.3
Downloading ruby-2.3.3.tar.bz2...
-> https://cache.ruby-lang.org/pub/ruby/2.3/ruby-2.3.3.tar.bz2
Installing ruby-2.3.3...

BUILD FAILED (OS X 10.11.6 using ruby-build 20160913)

Inspect or clean up the working tree at /var/folders/ff/fc49g5wd6xncjylvwy4tdygc0000gn/T/ruby-build.20170106013549.23791
Results logged to /var/folders/ff/fc49g5wd6xncjylvwy4tdygc0000gn/T/ruby-build.20170106013549.23791.log

Last 10 log lines:
  Referenced from: /private/var/folders/ff/fc49g5wd6xncjylvwy4tdygc0000gn/T/ruby-build.20170106013549.23791/ruby-2.3.3/./miniruby (which was built for Mac OS X 10.12)
  Expected in: /usr/lib/libSystem.B.dylib

dyld: Symbol not found: _clock_gettime
  Referenced from: /private/var/folders/ff/fc49g5wd6xncjylvwy4tdygc0000gn/T/ruby-build.20170106013549.23791/ruby-2.3.3/./miniruby (which was built for Mac OS X 10.12)
  Expected in: /usr/lib/libSystem.B.dylib

make: *** [.rbconfig.time] Trace/BPT trap: 5
make: *** Waiting for unfinished jobs....
make: *** [encdb.h] Trace/BPT trap: 5

10.12 ターゲットになってる。。。

わたしは、最新版を使ってないん。ApplemacOSXへの扱いが酷いので、最近は最新版を追いかけてない。1年弱遅れくらいでインストールすることにしてる。

なので、いまだに10.11のEl capitan なんですね。

xcodeのターゲットを変える必要がある。

takuya@Desktop$  xcode-select --install

その後インストールするとうまくいく

CC=/usr/bin/gcc \
CONFIGURE_OPTS="--with-readline-dir=/usr/local/opt/readline \
--with-openssl-dir=/usr/local/opt/openssl"\
rbenv install   2.3.3

いつものごとく、readline と openssl は homebrew のものを使った。

オプションはコレでよかったっけ。1年ぶり過ぎて忘れてる。。

参考資料

Xcode8環境下でrbenvにてrubyのコンパイルに失敗する - Qiita

bashの再起動execとbashrc を無視する起動オプション

bash の再起動方法

exec bash --login

bash の起動オプション

以下のオプションは、すべて同じ意味だと思っていい。

bash を起動してInteractiveShellとして起動する。設定ファイルなどはいつもどおりの順番で処理します。

bash --login 
bash -l
bash - 

exec の意味

exec は別のプロセスを実行して現在のプロセスを置き換える。

本来は、シェルスクリプトbash から起動した ruby などに処理を引き渡すなどに使う。

exec の例

#!/usr/bin/env bash 
ARGS=() #何か初期化

exec ruby my_script  ${ARGS[@]} # bashを終了してruby にする

exec bash で再起動

コレを合わせると、再起動になる。

exec で現在のbashを終了して、新しく起動したbash に切り替える。

$ exec bash --login

rc ファイルを指定する場合。

bash --rcfile ~/.bashrc.another

などとすれば、別のプロファイル( ~/.bashrc ) に切り替えられたりする。

rcも profile も使いたくない

なんも設定してない素のbashを使いたいと思ったら。

こんな設定で起動してやればいい。

bash --noprofile --norc

exec と組み合わせて戦える。

ただし変数は移行する

シェルからサブシェルを起動するときに環境変数は移行するので。。。

exec env -i  bash --norc --noprofile

env -i で 変数をignore して起動するとオッケー。

man からの抜粋

 -l   
  Make bash act as if it had been invoked as a login shell (see INVOCATION below).

--noprofile
 Do  not  read either the system-wide startup file /etc/profile or any of the personal initial-
 ization files ~/.bash_profile, ~/.bash_login, or ~/.profile.  By  default,  bash  reads  these
 files when it is invoked as a login shell (see INVOCATION below).

--norc Do  not  read  and execute the personal initialization file ~/.bashrc if the shell is interac-
 tive.  This option is on by default if the shell is invoked as sh.

--rcfile file
 Execute commands from file instead of the standard personal initialization file  ~/.bashrc  if
 the shell is interactive (see INVOCATION below).

ホンダのスマートキーの電池の交換について(N-BOX)

N-BOX のスマートキーの電池が切れた。

N-box のカギの電池切れたみたいなんですよね。なんかランプ点いた。

こんなの初めてなので、交換方法やランプの意味を調べておいた。

f:id:takuya_1st:20170105185725j:plain:w300

表示灯が突然点滅した。

運転中に、警告灯が点灯して焦った。

点滅する警告灯。

動画がにあるようにずっと点滅してました。

明滅してたら「電池切れ」が間近ってことですね。万が一バッテリー切れしたとしても、スマートキーはキーから取り出せばなんとかリカバリは出来るんだが。万が一は心臓に悪く、早速に取り替え方法や必要な部材を調べることにした。

youtu.be

説明書のスマートキーの交換方法

必要なボタン電池のサイズは<CR1632>だそうです。余り使わないので買い置きがないかもしれない。近隣のダイソーや100均もなかった。残念。

f:id:takuya_1st:20170106005437j:plain

スマートキーのこの部分からコインで開ける。

f:id:takuya_1st:20170106010753j:plain:w200

HONDAディーラーに交換をお願いした。

前を通る用事があったので、HONDAディーラーで交換をお願いした。

398円だった。良心的!

自分でやるのもいいけど、たまにはディーラーの営業マンとお話して顔を繋いでおくのもいいかもしれない。ディーラーに遊びに行くの楽しいしね。

ネットで見てみたらディーラーや車種によって値段は少し違うかも?

2−3年程度で切れるらしい

うちは、1000日(3年)で切れました。

ディーラーさんによると、使い方によってスペアキーも同時に切れたりするとのこと。

なので、購入するならスペアキーの分も買って同時に買えておくと変更周期が揃って嬉しいとのこと。

取扱説明書

HONDAの取扱説明書のスマートキーの電池交換の項目 → リンク

CR1632の電池について。

Amazonで200円程度で購入可能。→リンク

調べたら、ホンダの車種ごとに電池の種類は違うみたいですね。

bashの使い方のまとめ記事のインデックス

bash の使い方を1から見直すシリーズ

シェルスクリプトは、もうbashで書いていいよね。bashが動かない環境なんてないんだし。

bash の紛らわしい記号や歴史的経緯によるPOSIXかき分けなどがあって、bashに特化した記事って少ないし断片的なので、色々と調べたことを再構成してまとめて記事にしました。

私自身 [[ / [ の違いが全然わからないので調べ始めました。その結果あれこれ知見が得られたので書きながら復習をしていました。

気づけば、bash の教科書的なものになってしまいました。

何かの役に立てばいいと思って記事のインデックスをまとめておきます。まだ一部書けてないですがそのうち書きます。

はじめに

変数と配列と数値計算

  1. 変数
  2. 配列のまとめ
  3. 組込 let による数値計算とインクリメント
  4. 連想配列(assoc array / hash ) を使う。
  5. 文字列の追記(append)演算子の紹介
  6. 可変変数(抽象化)をする。
  7. 数値計算

変数の展開と置換

条件分岐とif の条件とループ

  1. 条件分岐 - if 以前の話
  2. 条件分岐 - if
  3. 条件判断 - 条件の一覧
  4. コマンドの終了ステータスの意味と見方

関数の定義と引数

正規表現とglob パターン

ループの構文のあれこれ

bashの似てて紛らわしいものシリーズ。

プロセスとジョブ

パイプ

環境変数

コマンドのオプション補完

知ってたら得する話。

関連リンク

参考資料

TODO

各ページに、記事間のリンクの貼ること

fio でHDD/SSDのブロックデバイスのベンチマークを取る

ブロックデバイスのベンチマークを取りたいと思いました。

ぱぱっとやる方法だと、 dd hdparm 等があるのですが、キャッシュなどいろいろ考えることも多いいので。今回は fio を試してみました。

まぁ普段の速度測定は dd でやっちゃうんだけどね。。。ネットワークは dd + ssh で。。。

fio のインストール

debian だと apt で一発ですね。さすがdebian

sudo apt install fio 

fio の確認

無事インストールされていることがわかる。

takuya@:~$ which fio
/usr/bin/fio

fio でテストする方法

fio でテストするためには、同じ条件でディスクを変えてテストすることになります。

このために、条件を一致させるための「ジョブファイル」というのを作るようです。

fio のジョブファイルのサンプル

takuya@:~$ cat myjob.fio
[Sequential-Read] # jobの名前
rw=read           # シーケンシャルでreadする
directory=/home/takuya/mnt/   # ベンチマークで使うディレクトリ
size=100m         # ベンチマークで使用するデータサイズ。キャッシュサイズを考慮して決める。
ioengine=libaio   # 非同期I/Oでテストする。指定しないとsync(同期I/O)になる。

[Sequential-Write]
rw=write          # シーケンシャルでwriteする
directory=/home/takuya/mnt/
size=100m
ioengine=libaio

[Random-Read]
rw=randread       # ランダムでreadする
directory=/home/takuya/mnt/
size=100m
ioengine=libaio

[Random-Write]
rw=randwrite      # ランダムでwriteする
directory=/home/takuya/mnt/
size=100m
ioengine=libaio

あとは実行

ジョブファイルを作ったら、コレを実行する。

takuya@:~$ fio myjob.fio

出力結果

結構あれこれ出力されるが、bw さえ見ておけば比較できると思う。

Sequential-Read: (groupid=0, jobs=1): err= 0: pid=19749: Wed Jan  4 20:35:30 2017
  read : io=102400KB, bw=48393KB/s, iops=12098, runt=  2116msec
Sequential-Write: (groupid=0, jobs=1): err= 0: pid=19750: Wed Jan  4 20:35:30 2017
  write: io=102400KB, bw=291738KB/s, iops=72934, runt=   351msec
Random-Read: (groupid=0, jobs=1): err= 0: pid=19751: Wed Jan  4 20:35:30 2017
  read : io=102400KB, bw=736685B/s, iops=179, runt=142337msec
Random-Write: (groupid=0, jobs=1): err= 0: pid=19752: Wed Jan  4 20:35:30 2017
  write: io=102400KB, bw=256000KB/s, iops=64000, runt=   400msec

読みづらい・・・出力単位をMB にしたい・・・unit を調べてみたけどkb_unit 設定しかなかった・・・

複数HDDのベンチマークを取って比較するジョブ・ファイルの構成

[HDD-A-Random-Write]
rw=randwrite      # ランダムでwriteする
directory=/home/takuya/mnt/
size=100m
ioengine=libaio
[HDD-B-Random-Write]
rw=randwrite      # ランダムでwriteする
directory=/tmp
size=100m
ioengine=libaio

こんな感じに複数作れば一回で終わる。

参考資料

http://qiita.com/smile-0yen/items/991ad53b8411364d9729

https://www.hitsumabushi.org/blog/2015/02/09/2227.html

bashの似てて紛らわしいもの ``バッククオートと $() について

似てて紛らわしいものシリーズ `バッククオートと $() について

bash の記号で初心者泣かせの、似てて紛らわしかったり、使い分けがわからなかったり、読み方を間違えてパニックになる記号について書く

``$( ) の違いのついて

コマンドの実行結果で置換される記述``$( ) はどちらもほぼ同じものです。

ただし、圧倒的な使いやすさの特徴差があります。それは複数重ねがけするときです。

ネストできる$() とネストが不便な ``

$() は重複して記述が圧倒的に楽です。

 echo $( dirname  $(realpath ~/Desktop/ )   )

同じことを バッククオートで書くとエスケープ地獄です。。。これはしんどすぎる。

 echo ` dirname  \`realpath ~/Desktop/ \`   `

ネストしないならバッククオートの方が読みやすいかも?

ネストしないなら、バッククオートの方が読みやすいかもしれない。

echo `brew --prefix`/opt/openssl
echo $(brew --prefix)/opt/openssl

この辺は使う人の好みなのかもしれないです。

rubyphpjavascript でもバッククオートをよく使うので慣れてる方が読みやすいと感じるのかも?