FreeBSD QandA 2002年2月3日 更新分

QandA
QandA Project
登録・更新 QandA 一覧

管理番号 2111 (新規) 更新履歴
Q. grep hoge * とすると、
     /usr/bin/grep: Argument list too long.
   となってしまいます。どうして?

A. 引数が長すぎるからです。

   ? や * などのワイルドカードの展開は sh や csh などのシェルが行います。その後、
   子プロセス (この場合は grep) を生成するのですが、このとき引数に指定できる長さ
   (バイト数) の上限は /usr/include/sys/syslimits.h で
     #define ARG_MAX 65536
   と設定されています。
     % sysctl kern.argmax
     kern.argmax: 65536
   としても参照できますが、動的な変更は不可能です。

   例えば、カレントディレクトリに 000000、000001、000002、000003…という
   ファイルがあった場合、
      grep hoge *
   とすると、シェルによって
      grep hoge 000000 000001 000002 000003 ....
   と展開されますが、そのときメモリ中には
      grep(\0)hoge(\0)000000(\0)000001(\0)000002(\0)000003 ....
   というデータが作成されます。このデータは execve(2) の第2引数に渡されますが、
   この長さが ARG_MAX を越えていた場合、カーネルがエラーを返し、シェルが
   Argument list too long というエラーを表示しているわけです。ちなみにこの
   データは、(execve が成功した場合は) 子プロセスの
     main(int argc, char **argv)
   の argv が指す領域となります。


   というわけで、こういう場合は、
     % echo * | xargs grep hoge
     % find . -type f | xargs grep hoge
     % find . -type f -print0 | xargs -0 grep hoge (ファイル名に空白などを含む場合)
   などとして、引数以外 (この場合は標準入出力) の方法でデータを受け渡します。

   また、とにかく引数に渡される文字列の長さを短くすればよいのですから、
     % grep hoge /usr/ports/*/*/pkg-plist
   が長すぎるなら
     % cd /usr/ports
     % grep */*/pkg-plist
   とすれば、`/usr/ports' の11バイト×ファイル数の分だけ短くなります。

   grep hoge * がダメで echo * が OK である理由は、sh や csh では echo が
   組み込みコマンドとなっていて、子プロセスを生成せず内部で処理するからです。
     echo が内部コマンドである証拠
       % sh
       $ type echo
       echo is a shell builtin
       $ csh
       % which echo
       echo is a shell built-in
   フルパスを指定して /bin/echo * とすれば、grep と同様に ARG_MAX の
   制限を受けます。


   参考:
     [FreeBSD-users-jp 53154] 以下のスレッド


管理番号 85 (更新) 更新履歴
Q. `panic: cannot mount root' で FreeBSD が起動しない。

A. FreeBSD を一台目以外の HDD にインストールしていますね。これはブートブ
   ロックとカーネルにおいて、HDD のユニット番号の認識が食い違っているため
   に起こります。この症状については FreeBSD FAQ にも解説がありますので、
   次の URL を参照してください。

   <URL:http://www.jp.FreeBSD.org/www.FreeBSD.org/ja/FAQ/install.html#PANIC-ON-INSTALL-REBOOT>

   1. FreeBSD 3.3-RELEASE 以降

   マシンを起動すると
      Hit [Enter] to boot immediately, or any other key for command prompt.
      Booting [kernel] in 9 seconds...
   という loader(8) のメッセージが表示されるので、ここでリターンキー以外
   のキーを押してコマンドモードに入り
      set root_disk_unit=2
      boot
   としてください。これで IDE ならセカンダリマスタから FreeBSD が起動する
   はずです。このとき指定する数字はインストールした HDD によって次のよう
   に読み換えてください。(GENERIC カーネルのとき)

       +-------------------------------+----------------------+
       |              IDE              |        SCSI          |
       +---------------+---------------+----------------------+
       |    Primary    |   Secondary   |                      |
       | Master  Slave | Master  Slave | 見付けた順に 0,1,2… |
       |   0       1   |   2       3   |                      |
       +---------------+---------------+----------------------+

   これで正しく FreeBSD がブートできたら
      # echo "root_disk_unit=2" >> /boot/loader.conf
   とすれば、次からブートローダでの指定はいらなくなります。設定ファイルは
   /boot/loader.conf.local でも良いのですが、どちらかに統一した方が後で
   混乱しなくて済みます。

   2. FreeBSD 3.2-RELEASE 以前

   起動時に `Boot:' と表示されたところで (3.0-RELEASE 以降では loader(8) 
   が読み込まれる前に Enter 以外のキーを叩くことで表示されます)、
   IDE + IDE で 2 番目の IDE がセカンダリのマスタの場合は
     1:wd(2,a)/kernel
   IDE + SCSI の場合は
     1:sd(0,a)/kernel
   を入力してください。
   IDE 2 台 + SCSI とか SCSI の 2 台目とかの場合は適宜 1: の数字や
   ?d(0,a) の 0 を 1,2 に変更してください。一般には、
     <BIOS>:<CTRLR>(<UNIT>,a)/kernel
   という形式で、
     <BIOS>  BIOS から見たディスクの番号。最初のドライブは `0'。
     <CTRLR> コントローラを指定します。
             IDE なら `wd'、SCSI は `sd' (3.0-RELEASE 以降では `da')
     <UNIT>  コントローラ上のドライブのユニット番号。上記の表を参照。
   です。

   なお次回のブート時にデフォルトとするには、
      # echo "1:wd(2,a)/kernel" > /boot.config
   のようにします。


管理番号 88 (更新) 更新履歴
Q. 1 台のパソコンを家族も使うことがあるので、「FreeBSD を起動する時は 
   フロッピーを入れる」という運用にしたい。

A. FreeBSD 2.2.5-RELEASE 以降なら以下の方法が使えます。
   フロッピーディスクをドライブに挿入し、

     # fdformat fd0
     # disklabel -w -B /dev/rfd0 fd1440
     # newfs /dev/rfd0

   とするか、インストールフロッピー (3.0-RELEASE 以降なら kern.flp、
   それより前なら boot.flp) を流用して、

     # mount /dev/fd0 /mnt
     # echo 'ad(0,a)' > /mnt/boot.config
     # umount /mnt

   これで reboot すればフロッピーから起動します。
   なお、`ad(0,a)' の部分については [管理番号 514] を参照してください。


管理番号 514 (更新) 更新履歴
Q. FreeBSD をインストールしたいんですが、ブートマネージャは HDD に書き込み
   たくありません。HDD の MBR を変更せずに FreeBSD を boot できるようにす
   る方法はありませんか?

A. インストールフロッピー (3.0-RELEASE 以降なら kern.flp、それより前なら 
   boot.flp) が使えます。

   まず最初に FreeBSD をインストールしますが、そのときブートマネージャ 
   (Boot Manager) を MBR に書き込むかどうかの問い合わせに `None' を選択し
   ます。そしてインストール終了後、もう一度上記のフロッピーをドライブに
   セットして reboot しますが、そのままでは loader(8) が読み込まれてしまい
   ますので、すかさず Enter 以外のキーを打ちます。すると次の樣なプロンプト
   が表示されます (FreeBSD 2.2.x では何もしなくても同様の状態になります)。

     >> FreeBSD/i386 BOOT
     Default: 0:fd(0,a)/boot/loader
     boot:

   ここで、`ad(0,a)' などとタイプすれば HDD から FreeBSD を起動することが
   できますが、FreeBSD をインストールした HDD によって以下のように指定し
   ます。

     ad(0,a)    IDE の Primary Master
     1:ad(2,a)  IDE 二台で Secondary Master
     da(1,a)    SCSI だけのシステムで二台目の HDD
     1:da(0,a)  IDE + SCSI で SCSI HDD

   より一般的には、
     <BIOS>:<CTRLR>(<UNIT>,a)<KERNEL>
   という形式で、
     <BIOS>  BIOS から見たディスクの番号。最初のドライブは `0'。
     <CTRLR> コントローラを指定します。
             IDE  … 4.0-RELEASE 以降 `ad'、それより前では `wd'
             SCSI … 3.0-RELEASE 以降 `da'、それより前では `sd'
     <UNIT>  コントローラ上のドライブのユニット番号。
             +-------------------------------+----------------------+
             |              IDE              |        SCSI          |
             +---------------+---------------+----------------------+
             |    Primary    |   Secondary   |                      |
             | Master  Slave | Master  Slave | 見付けた順に 0,1,2… |
             |   0       1   |   2       3   |                      |
             +---------------+---------------+----------------------+
     <KERNEL> /boot/loader または /kernel ですが、通常は省略できます。

   詳しくは boot(8) を参照してください。日本語訳を次の URL でも読むことが
   できます。<URL:http://www.jp.FreeBSD.org/man-jp/search.html>
   これで HDD からのブートに成功したら、いちいち入力する手間を省くために
   [管理番号 88] の設定を行ないます。


QandA
QandA Project
登録・更新 QandA 一覧