2015/08/03

組み込みLinuxの十徳ナイフ。多数のコマンドを集めたBusyBoxの概要と使い方

本記事は端末で用いるBusyBoxと呼ばれるツールについてをまとめたものとなる。

元の記事は2013年の9月から10月にかけて書かれたが、2つに分かれていた記事を統合し、カスタマイズなどの一部内容について追加・更新した。

  1. 概要
    1. 機能の実際
    2. スタンドアロン版とシステム破損時の復旧用途
    3. 組み込みでの用途とファイルサイズ
  2. ディストリなどによる機能の違い
  3. 外部コマンドとの機能の違い
  4. カスタマイズとビルド
  5. 使い方
    1. 引数で機能を指定する形
    2. シンボリックリンクを用いる形
    3. シンボリックリンクの自動生成
    4. 内蔵シェルの中からのコマンド実行

概要

BusyBoxはGNU/Linuxの基本コマンド群をはじめとする様々な機能を1つのプログラムにまとめたもの。ライセンスはGPLのバージョン2。

公式サイトmanページには “The Swiss Army Knife of Embedded Linux” と書かれており、日本語に訳すと “組み込みLinuxのスイス・アーミーナイフ” となる。 “スイス・アーミーナイフ” というのはナイフをはじめとする様々な道具を1つにまとめてコンパクトに折り畳めるようにしたもので、日本語で言うところの “十徳ナイフ” に当たり、BusyBoxにもこれに通じるところがある。

機能の実際

機能の全ては書ききれないため一部のみを挙げるが、それでも分類するとかなりの量になる。

  • ls, cp, mv, rm, ln, mkdir, rmdirのような基本的なファイル/ディレクトリ操作に関係するツール群
  • chmod, chown, chgrpのようなファイルのアクセス権操作に関係するツール群
  • echo, printfのような文字列出力やフォーマット付き出力に関係するコマンド群
  • head, tailのようなテキストファイルの端の一部のみを取り出すツール群
  • more, lessのようなテキストファイル閲覧ツール群
  • md5sum, sha1sumのような、ファイルのダイジェスト(ハッシュ)を計算するツール群
  • split, cat, tacのようなファイル分割/結合に関係するツール群
  • find, xargsのようなファイル検索に関係するツール群
  • gzip, gunzip, zcat, bzip2, bunzip2, bzcat, lzma, unlzma, lzcat, xz, unxz, xzcatのような単一ファイルの圧縮/伸長ツール群
  • cpio, tar, unzipのような一部の書庫を扱うツール群
  • rpm, rpm2cpio, dpkgのようなディストリのパッケージについての操作を行うツール群
  • ps, pidof, kill, killallのようなプロセス情報取得やプロセス制御に関係するツール群
  • grep, egrepのような、パターンによる内容検索を行うツール群
  • cmp, diffのような差分を扱うツール群と差分を適用するpatchコマンド
  • crond, crontabといったスケジューラ機能に関係するツール群
  • その他cd, pwd, cal, dmesg, seq, uniq, sort, cut, watch, date, sleep, touch, uname, expr, tee, stat, truncate, yesなどのコマンド群
  • ifconfig, ifup, ifdown, route, brctl, nslookup, ping(6), traceroute(6), nc, telnet, telnetd, netstat, ftpget, ftpputなど、ネットワーク関係の各種コマンド群
  • init, su, sulogin, mkfifo, mknod, mkswap, swapon, swapoff, modprobe, depmod, lsmod, chroot, klogdなど、多数の管理者向けツール群
  • mount, umountのようなマウント操作を行うツール群
  • Bシェル系の端末シェル
  • ed, sedのような非対話式のテキストエディタ
  • vi(対話式のエディタ)
  • getopt, expr, basename, dirnameのような、シェルスクリプトで使用したときに役に立つコマンド群

2015年8月上旬時点のドキュメントでは、下のような一覧となっている。

[引用]BusyBoxのmanページより
Currently available applets include:[, [[, acpid, addgroup, adduser, adjtimex, ar, arp, arping, ash,awk, basename, beep, blkid, brctl, bunzip2, bzcat, bzip2, cal, cat,catv, chat, chattr, chgrp, chmod, chown, chpasswd, chpst, chroot,chrt, chvt, cksum, clear, cmp, comm, cp, cpio, crond, crontab,cryptpw, cut, date, dc, dd, deallocvt, delgroup, deluser, depmod,devmem, df, dhcprelay, diff, dirname, dmesg, dnsd, dnsdomainname,dos2unix, dpkg, du, dumpkmap, dumpleases, echo, ed, egrep, eject,env, envdir, envuidgid, expand, expr, fakeidentd, false, fbset,fbsplash, fdflush, fdformat, fdisk, fgrep, find, findfs, flash_lock,flash_unlock, fold, free, freeramdisk, fsck, fsck.minix, fsync,ftpd, ftpget, ftpput, fuser, getopt, getty, grep, gunzip, gzip, hd,hdparm, head, hexdump, hostid, hostname, httpd, hush, hwclock, id,ifconfig, ifdown, ifenslave, ifplugd, ifup, inetd, init, inotifyd,insmod, install, ionice, ip, ipaddr, ipcalc, ipcrm, ipcs, iplink,iproute, iprule, iptunnel, kbd_mode, kill, killall, killall5, klogd,last, length, less, linux32, linux64, linuxrc, ln, loadfont,loadkmap, logger, login, logname, logread, losetup, lpd, lpq, lpr,ls, lsattr, lsmod, lzmacat, lzop, lzopcat, makemime, man, md5sum,mdev, mesg, microcom, mkdir, mkdosfs, mkfifo, mkfs.minix, mkfs.vfat,mknod, mkpasswd, mkswap, mktemp, modprobe, more, mount, mountpoint,mt, mv, nameif, nc, netstat, nice, nmeter, nohup, nslookup, od,openvt, passwd, patch, pgrep, pidof, ping, ping6, pipe_progress,pivot_root, pkill, popmaildir, printenv, printf, ps, pscan, pwd,raidautorun, rdate, rdev, readlink, readprofile, realpath,reformime, renice, reset, resize, rm, rmdir, rmmod, route, rpm,rpm2cpio, rtcwake, run-parts, runlevel, runsv, runsvdir, rx, script,scriptreplay, sed, sendmail, seq, setarch, setconsole, setfont,setkeycodes, setlogcons, setsid, setuidgid, sh, sha1sum, sha256sum,sha512sum, showkey, slattach, sleep, softlimit, sort, split,start-stop-daemon, stat, strings, stty, su, sulogin, sum, sv,svlogd, swapoff, swapon, switch_root, sync, sysctl, syslogd, tac,tail, tar, taskset, tcpsvd, tee, telnet, telnetd, test, tftp, tftpd,time, timeout, top, touch, tr, traceroute, true, tty, ttysize,udhcpc, udhcpd, udpsvd, umount, uname, uncompress, unexpand, uniq,unix2dos, unlzma, unlzop, unzip, uptime, usleep, uudecode, uuencode,vconfig, vi, vlock, volname, watch, watchdog, wc, wget, which, who,whoami, xargs, yes, zcat, zcip

スタンドアロン版とシステム破損時の復旧用途

BusyBoxは標準Cライブラリのみに依存し、ビルド時にこれを静的リンクする(中に取り込む)と、他の一切のファイルを必要とせずに動かすことができる(スタンドアロン版)。これはシステムが破損した場合の復旧に役立つ場合がある。

ディストリによっては “busybox-static” のように “static” と付くパッケージ名で静的リンク/スタンドアロン版が提供されている(例:Debian/Ubuntu)。静的リンク版をビルドするかどうかは、ビルド前の設定(カスタマイズ)時に決めることができる。

組み込みでの用途とファイルサイズ

“The Swiss Army Knife of Embedded Linux” と書かれているように、家電などの機械に搭載されるOS(組み込みOS)としてのLinuxの中で用いられる際にそのサイズの小ささと多機能さのバランスが良く、好んで用いられる。更に、BusyBoxはglibc系(派生版のEGLIBCも含む)のCライブラリよりもサイズが小さく組み込みOS向けな “µClibc” [1]というCライブラリに対応しており、ファイルサイズをより小さくすることもできる(ここでは扱わない)。[2]

ディストリなどによる機能の違い

BusyBoxはビルド時に機能の有効/無効などを細かくカスタマイズできるようになっているため、ディストリによって、ディストリ提供の(バイナリ)パッケージに含まれる機能が異なる場合がある。

本記事ではUbuntu 15.04のパッケージを使用している。

外部コマンドとの機能の違い

BusyBox内のコマンド機能は、それぞれの外部コマンド版と比べて対応しているオプションがかなり限られていたり、挙動に制限があったりする。例えば、一部の圧縮コマンドの圧縮率指定ができなかったり、diffがunified形式以外に対応していなかったり、その他色々なコマンドであまり使われないオプションが使えなかったりなどがある(軽量で組み込み向けなプログラムとして作られているので、無駄にファイルサイズが増えないようにそのようになっている)。コマンドごとのヘルプは “busybox [コマンド名] --help” を実行するか

(xzコマンドのヘルプを表示)
$ busybox xz --help
BusyBox v1.22.1 (Ubuntu 1:1.22.0-9ubuntu1) multi-call binary.

Usage: xz -d [-cf] [FILE]...

Decompress FILE (or stdin)

        -d      Decompress
        -c      Write to stdout
        -f      Force

もしくは後述の内蔵シェルの中で “[コマンド名] --help” を実行することでも参照できる。

カスタマイズとビルド

BusyBox内のそれぞれのコマンドなどの機能は “アプレット(applet)” と呼ばれ、ビルド前の設定時に必要なものだけを有効(逆に言えば不要なものを無効)にして、ビルドして生成される実行ファイルのサイズを用途に合わせて小さくすることができる。ちなみに、先述のµClibcも同様に機能の有効/無効を用途に合わせてカスタマイズでき、両方を用途に合わせて適切に設定しつつµClibcを用いるようにすることで、サイズをかなりコンパクトに抑えることができる。

機能のカスタマイズは、Linuxのカーネルで使用されているものと同様の(階層構造を持った)ビルド設定ツールを用いて行う。

以下は端末用の “menuconfig” ターゲットでの作業例で、libncursesライブラリの開発パッケージ(Debian/Ubuntuでは “libncurses[数字]-dev” パッケージ)が必要。GUI環境では “gconfig” (GTK+ 2版設定ツール)のターゲットも指定できる(libglade 2の開発パッケージが必要)。

(端末でビルド設定を行う)
[busybox-x.y.z]$ make menuconfig

端末で動作する設定ツール

矢印キーで項目を移動し、下部の “Select” が選択されている状態で Enterを押すことで決定する。 “--->” の項目はサブメニューに進むもので、階層を戻るには左右矢印キーで下部の “Exit” が選択されている状態でEnterを押す。設定項目の説明は下部の “Help” が選択されている状態でEnterを押すと参照できる[3]。これらはLinuxのカーネル設定を端末で行う場合と同様。

  • 項目の操作は下のようになる
    • 角括弧(オン/オフ)[4]: y(有効)/n(無効)、もしくはSPACEで切り替え
    • 丸括弧(数値や文字列): Enter後内容を入力
    • 選択肢(いずれか1つを選択): EnterもしくはSPACE
  • “Busybox Settings” で本体やそのビルド関係の設定を行う
  • “Applets” 以下の各メニューで各機能の有効/無効などに関する設定を行う
  • ビルド設定ファイルの読み書きはカーネルと同様
    • “Save Configuration to an Alternate File” でファイル名(既定値は.config)を指定して保存
    • “Load an Alternate Configuration File” で保存済みの設定ファイルを読み込む(あらかじめ.configという名前で用意しておくと楽)

設定が.configに保存された状態でmakeを実行するとビルドが行われ、実行ファイルbusyboxが作成される。

(ビルドを行う)
[busybox-x.y.z]$ make (オプション...)

使い方

引数で機能を指定する形

上のヘルプ表示のように、busyboxコマンドの引数としてコマンド名とそのオプションや引数を付けていく形。

(BusyBox版のechoコマンドを実行するテスト)
$ busybox echo -e "abc\tdef\nghi"
abc[タブ]def
ghi

(viエディタを起動・起動後の操作は終了含めviエディタのものとなる)
$ busybox vi

シンボリックリンクを用いる形

busyboxの実行ファイルの場所を指し示すシンボリックリンクを、呼び出したいコマンドの名前で作成する。すると、このシンボリックリンクはその名前のコマンドのように動作する。下はlnのシンボリックリンクを作成した後でこれを用いてmkdirlsのシンボリックリンクを作成し、その後それらを実行しているテスト。

(lnコマンドとしてのシンボリックリンクを現在の作業ディレクトリに作成)
$ busybox ln -s /bin/busybox ln

(シンボリックリンクのlnでmkdirコマンドとしてのシンボリックリンクを現在の作業ディレクトリに作成)
$ ./ln -s /bin/busybox mkdir

(シンボリックリンクのlnでlsコマンドとしてのシンボリックリンクを現在の作業ディレクトリに作成)
$ ./ln -s /bin/busybox ls

(シンボリックリンクのmkdirで新しいディレクトリを作成)
$ ./mkdir newdir

(シンボリックリンクのlsで現在の作業ディレクトリの項目一覧を表示)
$ ./ls -F
ln@     ls@     mkdir@  newdir/

シンボリックリンクの自動生成

--install -s” オプションを付けて実行すると、現在のBusyBoxがサポートする全てのコマンド名のシンボリックリンクを自動的に指定ディレクトリに作成することができる。

(全てのコマンドのシンボリックリンクを指定ディレクトリに作成)
$ busybox --install -s /path/to/bin
(seqコマンドを試しに実行)
$ /path/to/bin/seq 3
1
2
3

内蔵シェルの中からのコマンド実行

“ash” と呼ばれる機能で、dashのようなBシェル系の軽量シェルが利用できる(ビルド時に有効になっている場合)。この中で用いる内部コマンドはBusyBox版が優先される。利用可能な内部コマンドの一覧はhelpという内部コマンドで確認できる。なお、 “ash” よりも機能が制限されるがよりサイズの小さな “hush” というシェルも存在する。どちらもビルド時の設定である程度の機能カスタマイズができる。

下はテストの例。

(ashのシェルに入る)
$ busybox ash

(使用可能コマンドの一覧を表示/ディストリによって一覧の表示内容は異なる)
[busybox ash]$ help
Built-in commands:
------------------
        . : [ [[ alias bg break cd chdir command continue echo eval exec
        exit export false fg getopts hash help history jobs kill let
        local printf pwd read readonly return set shift source test times

        ...

        udhcpd umount uname uncompress unexpand uniq unix2dos unlzma
        unlzop unxz unzip uptime usleep uudecode uuencode vconfig vi
        watch watchdog wc wget which who whoami xargs xz xzcat yes zcat

(seqコマンドで連番を出力)
[busybox ash]$ seq -w 12
01
02
03

...

10
11
12

(カレンダーを表示)
[busybox ash]$ cal 8 2015
    August 2015
Su Mo Tu We Th Fr Sa
                   1
 2  3  4  5  6  7  8
 9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31

(gzipコマンドのヘルプを表示)
[busybox ash]$ gzip --help
BusyBox v1.22.1 (Ubuntu 1:1.22.0-9ubuntu1) multi-call binary.

Usage: gzip [-cfd] [FILE]...

Compress FILEs (or stdin)

        -d      Decompress
        -c      Write to stdout
        -f      Force
使用したバージョン:
  • BusyBox 1.22.1
[1]: “uClibc” とも書かれる
[2]: “Buildroot” と呼ばれるツールを用いるとµClibcを用いるビルド環境が作れる
[3]: 設定項目がない階層では操作説明などの文書が表示される
[4]: カーネル設定とは異なり、モジュール形式にできる設定項目(2つの不等号による括弧)はない