FreeBSD QandA 2002年2月3日 更新分
管理番号 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] の設定を行ないます。