今日須崎ケーブルテレビ と契約をした。CATVインターネットのモニターを募集していたからです。これの良いところは 電話代を気にせずwebサーフィンできて、ダイアルアップよりもはるかに早いということ です。
LANボードがもう一枚いるということで(もう一枚は家庭内LAN用つまり2枚挿しになる) 買うことにしました。パーツを買う時、筆者はインターネットショップを良く利用する。 今回は送料が無料で品数の多いPC-PARK にアクセスしてみたするとプラネックッスコミュニケーションズ(株)のENW-8300-T (PCIバス 10Base-T)が1,110円だったのでこれに決めた。
LANボードには100Base-Tと10Bese-Tの2種類のものが有る。CATVの場合には10Base-T
のボードが使われる。IPアドレスはDHCPサーバより取得となっている。Windowsの設定は
解るのだがFreeBSDの設定はややこしい。
FreeBSD QandA 392
によるとDHCPサーバ、クライアントにはwide版とisc版があるようです。isc版は
FreeBSD 3.2-RELESE以降のものには標準で付いているとのことで、我が家には
FreeBSDをインストールしたパソコンが2だい有って、一方が3.1でもう一つは3.4なので
この3.4の方をDHCPクライアントにすることにした。設定ファイルは/etc/dhclientですが
このなかで /etc/dhclient-scriptを使っているこの中身をみてみると/etc/resolv.conf
を書き換えるようである。我が家ではDNSサーバを立ち上げているのでちょっと都合が悪い。
<補足>resolv.confをresolv.conf.dhclient
のように書き換えるようにスクリプトの内容を変更しています。
dhclientの起動方法は/etc/rc.confにifconfig_ed0="DHCP"(ed0はインタフェース名)
を追加するか
rootでコマンドラインからdhclient ed0 とタイプしてもよいです
LANボードのENW-8300-TをTYAN Trinity 400 に付けることにした。FreeBSDでの認識は 以下のようなものです。
ed1: <NE2000 PCI Ethernet (RealTek 8029)> rev 0x00 int a irq 3 on pci0.17.0
ed1: address 00:90:cc:a4:37:c5, type NE2000 (16 bit)
rl0: <RealTek 8139 10/100BaseTX> rev 0x10 int a irq 11 on pci0.20.0
rl0: Ethernet address: 00:00:e8:9f:4f:49
rl0: autoneg complete, link status good (half-duplex, 10Mbps)
新しく付けたENW-8300-Tはed1として認識された。rl0は内部ネットワーク用に前から 付けていたものです。実はこのLANボード、どこにもベンダー名が記されていない。 ミックで1280円で買ったものだ。
FreeBSDでNAT(Network Adress Translator)をするためにはnatdを使う方法とip-filter を使う方法が有る。今回はnatdを使う方法がTRY!PC4月号に掲載されていたのでnatdを 使ってみることにした。 (NATに関しては RFC1631を参照してください。)
# cd /sys/i386/conf以上で設定は終りです。
# cp GENERIC MYKERNEL
# vi MYKERNEL
編集内容
不必要な行を#でコメントアウトする。(不可欠なものまで#を付けないように注意)
pseud-device bpfilter 1 #Berkeley packet filter
の数字を1から4に変更する。
以下の2行を追加する。
options IPFIREWALL
options IPDIVERT
以上が編集内容です。
# config MYKERNEL
# cd ../../compile
# make depend
# make
# make install
以上でカーネルの再構築は終りです。
次にデバイスファイルを作ります。
# cd /dev
# sh MAKEDEV bpf3
/etc/rc.confに以下の行を追加します。
natd_enable="YES"
natd_interface="ed1" #ケーブルモデムにつなげるLANボードのインタフェイス、ここではed1
natd_flags="-s -m -dynamic"
firewall_enable="YES"
firewall_type="open"
リブートします。
# shutdown -r now
今日はCATVの工事です。工事は2時間ぐらいかかりました。DHCPクライアントの設定は /stand/sysinstallでやってみることにしました。Interfaceの設定でed1を選択後 "DHCPの設定を試してみますか?"に"はい"を選択すると自動でゲートウェイアドレス DNSサーバアドレスIPアドレスなどが設定される。気になる設定ファイルであるが /etc/rc.confには ifconfig_ed1="DHCP"が追加されている。/etc/resolv.confは新しいネームサーバの アドレスになっていた。気になる/etc/dhclient.confであるが中身はコメント行 があるだけでした。リブートして以下の行を試してみました。
% ifconfig -a ed1: flags=8843mtu 1500 inet 192.168.XXX.XXX netmask 0xffffff00 broadcast 192.168.XXX.255 ether 00:90:cc:a4:37:c5 <以下略>
inet 192.168.XXX.XXXがDHCPサーバより割り当てられたIPアドレスです。 このIPアドレス毎回違うものが割り当てられると思っていたのだがいつも同じ のようです。/var/db/dhclient.leasesにこのIPアドレスのリース期間が記述 されている。renewの項目が2017になっていることから西暦2017年までこのIPアドレス らしい。別のパソコンからもwebにアクセスできた。別にこのようにめんどうなことを しなくてもケーブルモデムからの10Base-Tのケーブルをハブにつないで各パソコンを DHCPクライアントにすればよいのだがnatdを試してみたかったことがあった。現に このようなつなぎ方を認めていないCATVもあります。つまりケーブルモデムにつなぐ パソコンは1台だけで複数台つなぐ場合はそのパソコンにproxyサーバソフトを インストールしてくださいというようなものです。
現在ケーブルモデムは3Comのサメのヒレの形をしたものに 変更になりました。このモデムは一つのLANボードしか認識しないのでHUBにつないで 複数のパソコンがケーブルテレビのDHCPサーバからIPアドレスを取得することはでき ません。
yahooのオークション でエプソンのスキャナGT-8500を落札した。落札価格は9250円である。古い機種なので少し高かったかも しれない。ただ付けてくれたスカジケーブルのパソコン側のコネクタが合わず近所の 電機屋に買いに行ったが8000円もした。ケーブルがこれほど高いとは計算に入れてなかった。 FreeBSDでスキャナを使うにはsaneというソフトを使う。Windowsで使うTWAINのようなものだ。 GT-5500とGT-7000は動くようである。GT-8500は動くかどうかわからない。
FreeBSDにソフトをインストールするにはpackageかportsをつかう。packageを使った方が 簡単で確実にインストールできるのだが今回はportsを使ってみることにした。しかも スカジボードの付いているマシンはFreeBSD3.1でportsツリーも古くなっているのでこれを cvsupで新しいものに変えることにした。まずcvsupのインストールportを試みたがエラーで ストップ、しかたなくpackageでインストール、つぎに3.1から3-stableへのアップグレード キットをpkg_addする。そして/usr/share/examples/cvsup/ports-supfileを~/my_ports-supfile などとコピーし編集する。変更箇所は*default host=CHANGE_THIS.Free.BSD.orgの所を *default host=cvsup2.jp.FreeBSD.orgのように変え、*default base=/usrを *default base=/usr/local/etc/cvsupとする。X上でcvsup my_ports-supfile とすると、ウィンドウが開きファイルのダウンロードが始まり/usr/ports以下のファイルを 更新してゆく、だいたい18k/sのスピードである。ダイアルアップの時は早くても6〜7K/s だったので、約3倍のスピードである。これが終るとcd /usr/ports/grahics/saneとし makeとタイプした。がgtk12のconfigureの所でエラーになりストップした。portsでインストール する時はよくあることである。
スキャナのepson GT-8500がsane1.02で動作しました。 動作リストにはGT-8500はなかったけれど 問題なく画像をスキャンできました。スキャンした画像は これです。
インストールの方はなかなかうまくいかなかったのですが簡単に手順を言うとXfree86-3.3.3.1を XFree86-3.3.3.6にバージョンアップ、gtkのconfigureでエラーになることから古いバージョンのgtkを削除して みてはどうかということでgtk-1.0.,gtk-1.1.*をpkg_deleteするのですが、 依存関係があるのでenlightenment-0.15.*,gimp,imlib,を先に削除しますgtkを削除したらglibも削除します。 まずenlightenmentをインストール。cd /usr/ports/x11-wm/enlightenmentとしてmake バージョンは0.16.4です。しかしまたもやgtk12でストップ、しかたないのでgtk12はpackageで インストールしました。そうするとenlightenmentのmakeがとおりインストールすることができました。 enlightenmentを立ち上げて見ると見事に起動しました。やはりいいですねenlightenmentは。 バージョンアップをして良かったと思いました。 次にgimpをインストールです。バージョンは1.1.24です。順調にmakeしていきましたが、 libxpg4.so.3がないといってstopしてしまいました。そこで 検索のページで探してみると ln -s /usr/bin/libxpg4.so.2 /usr/bin/libxpg4.so.3とすれば良いという投稿があったので そのようにすればmakeすることができました。gimpのインストールの次がsane-1.02です。 これはmake ; make installですんなりできました。
# camcontrol devlist < > at scbus-1 target -1 lun -1 (xpt0) <EPSON SCANNER GT-8500 1.26> at scbus0 target 5 lun 0 (pass0) <MATSHITA CD-R CW-7502 4.10> at scbus0 target 6 lun 0 (pass1,cd0) < > at scbus0 target -1 lun -1 ()
スキャナは/dev/pass0で認識されています。そこで
# cat /usr/local/etc/sane.d/epson.conf
/dev/scanner
となっていますので、これを/dev/pass0のように書き換えます。
/dev/pass0を一般ユーザーからもアクセスできるようにします。
# chmod 666 /dev/pass0
一般ユーザに戻ってxscanimageをgimpから使えるようにリンクを張ります。
% mkdir ~/.gimp-1.1/plug-ins
% ln -s /usr/local/bin/xscanimage ~/.gimp-1.1/plug-ins
% scanimage --help
最後に利用可能なデバイスのリストが表示されます。
List of available devices:
epson:/dev/pass0
% setenv LANG ja_JP.EUC
% gimp.setfont japanese
% gimp &
拡張 -> Acquire Image -> Device dialogまたはepson:/dev/pass0とすると
xscanimageが起動されます。スクリーンショットはこれ(158K)です。
SANEのホームページhttp://www.mostang.com/sane/
日本語ドキュメント
SANE-outline-JP
SANE-tutorial-JP
ちなみにsane-1.00は問題ありです。sane-1.01は動きます。
40060
40067
前にFreeBSDでNAT(Network Addrress Traslator)を実現する方法natdを紹介したがもう一つの 方法のIP-FILTERの設定について述べてみます。 LANボードは2枚挿しでケーブルモデムにつながっているボードはed1で認識され、DHCPクライアント は設定済とします。
# cd /sys/i386/conf
# cp GENERIC MYKERNEL
# vi MYKERNEL
ident GENERICをMYKERNELとする
以下の2行を追加する。
options IPFILTER
options IPFILTER_LOG
bpf(Berkley Packet Filter)を有効にし、フィルターの数を1から4に変更する。
pseudo-device bpfilter 4 #Berkeley packet filter
以上が編集内容です。
# config MYKERNEL
# cd ../../compile/MYKERNEL
# make depend
# make
# make install
bpfのデバイスファイルを作ります。
# cd /dev
# sh MAKEDEV bpf0 bpf1 bpf2 bpf3 設定ファイルを編集します。
# vi /etc/ipf.conf
pass in from any to any
pass out from any to any
# vi /etc/ipnat.conf
map ed1 192.168.1.0/24 -> 0/32 portmap tcp/udp 10000:65000
map ed1 192.168.1.0/24 -> 0/32
ed1はケーブルモデムにつながっているインタフェース名です。
ダイアルアップの場合はtun0のようになります。
192.168.1.0/24は内部ネットワークのIPアドレスです。
この例では192.168.1.1〜192.168.1.224のアドレスになります。
# vi /etc/rc.local
/sbin/ipf -f /etc/ipf.conf
/usr/sbin/ipnat -f /etc/ipnat.conf
# vi /etc/rc.conf
gateway_enable="YES"を追加します。
# shutdown -r now
以上です。
IP-FILTERについての詳しい情報は http://cheops.anu.edu.au/~avalon/ip-filter.htmlを参考にしてください。
FreeBSD 4.4での設定は少し違っていました。 これを参考にしてください。
マザーボードはTyan S1854 Trinity 400,ハードディスクはseagate ST313021A,12419MB w/512kB Cache,CHS=1583/255/63です。このマシンには Windows98 2.4G FreeBSD 4.3G Windows2000 3.2G 残り2.6Gでパーテションされており この残り2.6Gにlinuxをインストールするのですが、一つ問題があってlinux標準のブートローダであるliloは1024シリンダまたは8Gを越える領域のOSは起動できないのです。 そこでliloはMBRにインストールせずにルートパーテションにインストールして MBRにブートセレクターのMBM などをインストールすれば良いかなと思ったのですが、この方法はだめでした。 順をおって説明して行きます。
BIOSでブートの順番をCD-ROMから起動できるように変更してインストーラを 起動します。ところがなぜかCD-ROMが認識されないのです。しかたないので NFS(Network File System)でインストールすることにした。別のFreeBSDマシンを NFSサーバにするのですが、NFSについては以前から知っていたのですが設定の 方法がわからなかった。 捜して見ると ハンドブック16.4. NFSにのっていた。 ハンドブックは 更新され続けているようである。ローカルマシンのハンドブックにはのっていない。
NFSサーバの設定これで別のFreeBSDマシンのCD-ROMを使えるようになりました。
# vi /etc/rc.conf
nfs_server_enable="YES"# vi /etc/exports
nfs_server_flags="-u -t -n 4"
mountd_flags="-r"
/cdrom -ro <マシン1> <マシン2> <マシン3>再起動するか以下のコマンドを実行する
-roはリードオンリー、マシン1、2、3は/etc/hostsに記述されているもの
# nfsd -u -t -n 4
# mountd -r
liloをルートパーティションにインストールするのですがエラーになって インストールできません。 サポートのFAQ によるとルートパーティションが拡張領域にあるとエラーになるそうです。 そこでliloを使うのはあきらめて liloを使わずにシステムを起動する方法がサポートのFAQにあったので これでやってみるとlinuxを起動することができました。
[root@kitora manabe]# /sbin/fdisk -l ディスク /dev/hda: ヘッド 255, セクタ 63, シリンダ 1583 ユニット = シリンダ数 of 16065 * 512 バイト デバイス ブート 始点 終点 ブロック ID システム /dev/hda1 * 1 309 2482011 b Win95 FAT32 /dev/hda2 310 850 4345582+ a5 BSD/386 /dev/hda3 851 1250 3213000 7 HPFS/NTFS /dev/hda4 1251 1583 2674822+ 5 拡張領域 /dev/hda5 1251 1581 2658726 83 Linux /dev/hda6 1582 1583 16033+ 82 Linux スワップ hda: ST313021A, 12419MB w/512kB Cache, CHS=1583/255/63
kterm上で実行した結果です。日本語で表示されるのがすごい。これでみるとLinuxの 領域は拡張領域になっています。基本領域は一つのHDDに4つまでとなっているので Linuxスワップの領域があるためLinuxの領域は必然的に拡張領域となるのではないか。
<注意>ここでは重大な計算間違いをしています。なんと スワップ領域が8.2MBしかありません。スワップ領域は実メモリの2倍、実メモリが 512MB以上の場合は同じかそれ以上とる必要があります。 しかしこれでも問題無く動作しました。
[root@kitora manabe]# /sbin/lilo Warning: device 0x0305 exceeds 1024 cylinder limit Fatal: geo_comp_addr: Cylinder number is too big (1462 > 1023)
これをみるとliloは基本領域でも1024シリンダ以降はインストールできないのでは ないだろうか。CD-ROMを認識させるためにはLILO:とプロンプトに続けて hdc=cdromとタイプしなければならないとやら。CD-ROMもあきらめるか。
liloを使わずにシステムを起動する方法では GNU GRUBを紹介しています。キー配列が違うので注意。grub> root (hd0,4) Filesystem type is ext2fs, partition type 0x83 grub> kernel /boot/vmlinuz-2.2.13-33 root=/dev/hda5 [Linux-bzImage, setup=0xe00, size=0xa09e0] grub> boot -------- grub> root (hd0,1,a) Filesystem type is ffs, partition type 0x7a5 grub> kernel /kernel [FreeBSD-elf, <0x100000:0x148072:0x0>,<0x249074:0x1b360:0x21e30>,entry=0x1186f0] grub> boot --------- grub> root(hd0,0) Filesystem type is fat, partition type 0xb grub> chainloader +1 grub> boot
前回に引続きTurbolinuxの話題です。FreeBSDと基本的なコマンドは共通していますが違うところもあるので。インストールのときCD-ROMが認識しなかったのはなぜだろう CD-ROMが使えないのは面白くない。
$ dmesg | less . . hda: ST313021A, ATA DISK drive hdc: ATAPI CD ROM DRIVE 40X MAX, ATAPI CDROM drive ide0 at 0x1f0-0x1f7,0x3f6 on irq 14 ide1 at 0x170-0x177,0x376 on irq 15 hda: ST313021A, 12419MB w/512kB Cache, CHS=1583/255/63 hdc: packet command error: status=0x51 { DriveReady SeekComplete Error } hdc: packet command error: error=0x54 ATAPI device hdc: Error: Illegal request -- (Sense key=0x05) Parameter list length error -- (asc=0x1a, ascq=0x00) The failed "Mode Sense" packet command was: "5a 00 2a 00 00 00 00 00 18 00 00 00 " hdc: packet command error: status=0x51 { DriveReady SeekComplete Error } hdc: packet command error: error=0x54 ATAPI device hdc: Error: Illegal request -- (Sense key=0x05) Parameter list length error -- (asc=0x1a, ascq=0x00) The failed "Mode Sense" packet command was: "5a 00 2a 00 00 00 00 00 18 00 00 00 " Uniform CDROM driver Revision: 2.56 以下略
CD-ROMはセカンダリのマスタに接続している。hdc: packet command error と言うエラーが出ている。日本のLinux情報 で調べてみるとこれはCD-ROMがメディアを読みにいっているのではないかと判断して メディアを入れて再起動させてみたが同じでした。/etc/fstabには/mnt/cdromの 項目がありません。hdc: ATAPI CD云々とあることからなんか使えるようになっているのではないかという気がします。JFのIDE-CDドライバに関する文書や これで述べているローカルファイルfile:/usr/src/linux-2.2.13/Documentation/ide.txtが参考になります。
# ln -s /dev/hdc /dev/cdrom # mount -t cd9660 -o ro /dev/cdrom /mnt/cdrom #
エラーメッセージが返ってこなければマウントできた ことになります。何だ最初から使えるようになっていたのかという感じです。 /dev/cdromの代わりに/dev/hdcでもOKです。"-o ro"はリードオンリーのオプションです。"-t cd9660"でファイルシステムのタイプの指定ですが省略できます。
# cat /proc/filesystems ext2 nodev proc iso9660 nodev devpts vfat hpfs
ここにファイルシステムが登録されていれば自動でマウントするようです。 マウントをはずすのは/mnt/cdrom以外のディレクトリに移動してumount /mnt/cdrom です。CD-ROMが使えるのがわかったので/etc/fstabに/dev/cdromの項目を追加します。
# vi /etc/fstab /dev/hda5 / ext2 defaults 1 1 /dev/hda1 /dos vfat defaults 0 0 /dev/hda3 /nt hpfs defaults 0 0 /dev/hda6 swap swap defaults 0 0 /dev/fd0 /mnt/floppy ext2 noauto,user 0 0 /dev/cdrom /mnt/cdrom iso9660 noauto,ro,user 0 0 proc /proc proc defaults 0 0 none /dev/pts devpts mode=0622 0 0
/dev/hda3はntfsですがmountできません。またFreeBSDの領域もlinuxからはmount できません。
例えばあるディレクトリに001.html,002.html・・・400.htmlのように400個の htmlファイルを作らなければならない、そしてそれぞれのファイルは一箇所だけ 違っている。
% cat 001.html <html> <head> </head> <body bgcolor="white" text="black"> <center> <img src="img/001.jpg" border="0"> </center> </body> </html>
上記のimg src="img/001.jpg"の所001が002,003,004・・・400のように変化する。 これを一つ一つ書いていたのでは非常に時間がかかる。そこで001.htmlだけ書いて あとの002.htmlから400.htmlはシェルスクリプトでやってみることにする。
% cat > html.sh #!/bin/sh COUNT=1 while [ $COUNT -lt 400 ] do COUNT=`expr $COUNT + 1` sed "s/001/`printf "%03s" $COUNT`/" 001.html > `printf "%08s" ${COUNT}.html` done Ctrlキーを押しながらDキーを叩く
html.shというファイルを作りchmod +x html.shとして実行権をあたえ./html.shとして 実行してみる。./はカレントディレクトリを表す、実行ファイルはカレントディレクトリ にあってもパスを表示しないと実行されません。(FreeBSDで)するとのこり399個 のファイルができます。これは何個でも同じで上記の400の所を好きな数字に変えればよい
#!/bin/sh Bシェルの宣言をします。 COUNT=1 変数"COUNT"に1を代入します。"="の両辺にはスペースをいれません。 while [ $COUNT -lt 400 ] 変数"COUNT"が400より少ない場合はdoからdoneの間のことを繰り返す。 変数を参照する時は$(ドルマーク)を付けます。-ltはLess Thanの略で より少ないという意味。以下本の写しですが -lt 未満 less than -le 以下 less equal -eq 同じ equal -ge 以上 greater equal -gt より上 greater than -ne 等しくない not equal COUNT=`expr $COUNT + 1` 変数"COUNT"に1を足して変数"COUNT"に代入します。 `(逆シングル・クオテーション)で囲っていることに注意してください。 exprというコマンドが含まれるために、ここは'(シングル・クオテーション) ではなく`(逆シングル・クオテーショオン)で囲みます。exprは式を評価 するコマンドです。 sed "s/001/`printf "%03s" $COUNT`/" 001.html > `printf "%08s" ${COUNT}.html` sedはストリームエディタと呼ばれるものです。001.htmlから001の文字列を `printf "%03s" $COUNT`で出力された文字列に変換し `printf "%08s" ${COUNT}.html`で出力されたファイルに書き出します。 printfは書式設定をするコマンドで "%03s"の 0 は空白部分を 0で埋め、 3は3桁の意味、sは文字列です。$COUNTは 2,3,4…50…400が002,003,004 …050…400のように変換されます。sedの書式は次のようなものです。 sed 's/変換対象文字列/変換後の文字列/g' 変換前ファイル > 変換後ファイル gは一行内で繰り返し変換を行なうためのフラグ これがないと最初に でて来る文字列だけしか変換されません。また今回の例では '(シングル・ クオテーション)ではなく "(ダブル・クオテーション)で囲っていることに 注目してください。これがシングル・クオテーションだと `printf "%03s" $COUNT`の部分をそのまんまの文字列であるとシェルは 解釈します。
FreeBSD快適操縦ガイド 山口至著 メディア・テック出版WindowsやMacはユーザーがお金を払うためのOSで それにたいしてUNIXはユーザが お金を生み出すOSと言っている。UNIXとは凄いんだなと思いました。
UNIXプログラミング環境Brian W.kernighan, Rob Pike,石田晴久 監訳、アスキー 出版局良く使うコマンドやシェルスクリプトの解説など初心者向けに書かれた本です。 とても参考になりました。
古い本ではあるが、古典的名著らしい。初心者にはとっつきにくいかも知れないが モガミワイヤーさんの言うUNIXの思想を理解するのには良いかも。
今回はカレントディレクトリのJEPEG画像をすべてサムネイルで表示する HTMLを作ります。
% ls ant.jpg butterfly.jpg cow.jpg horse.jpg raccoon.jpg bird.jpg cat.jpg dog.jpg mouse.jpg sheep.jpg
このようなファイルがあるとします。これらの画像ファイルを元の大きさの 10%で全て表示するHTMLを作るプログラムです。これをthumbnail.shとします。
% cat thumbnail.sh #!/bin/sh printf "<html>\n<head>\n</head>\n<body>\n" > THUMBNL.html for i in `ls *.jpg` do echo "<img src=\""$i"\" width=\"10%\" heigt=\"10%\">" >> THUMBNL.html done printf "</body>\n</html>\n" >> THUMBNL.html
これにchmod +x thumbnail.shとし~/binにコピーしておくと良いでしょう。 source ~/.loginとして実行してみましょう。
(補足:ログインシェルがcshの場合です。~/.loginのset pat = のところに $HOME/binの記述がなくては行けません。shのばあいは~/.profileです。)% thumbnail.sh % ls THUMBNL.html butterfly.jpg dog.jpg raccoon.jpg ant.jpg cat.jpg horse.jpg sheep.jpg bird.jpg cow.jpg mouse.jpg
THUMBNL.htmlというファイルができています。
% cat THUMBNL.html <html> <head> </head> <body> <img src="ant.jpg" width="10%" heigt="10%"> <img src="bird.jpg" width="10%" heigt="10%"> <img src="butterfly.jpg" width="10%" heigt="10%"> <img src="cat.jpg" width="10%" heigt="10%"> <img src="cow.jpg" width="10%" heigt="10%"> <img src="dog.jpg" width="10%" heigt="10%"> <img src="horse.jpg" width="10%" heigt="10%"> <img src="mouse.jpg" width="10%" heigt="10%"> <img src="raccoon.jpg" width="10%" heigt="10%"> <img src="sheep.jpg" width="10%" heigt="10%"> </body> </html>
画像が何百個あっても同じです。そのかわり読み込みに時間が かかりますが。このように簡単なコマンドの組合せで面白いことができるのが シェルプログラミングの魅力です。
友人からパソコンの見積り依頼があった。
% cat mistumori.txt CASE MaxPoint CS-658QX 300W電源 Pentium4対応 \8,980 faith MB ECS K7VZA v3.0 KT133A(266mhzCPU対応) \10,970 faith CPU K7 Athlon ThunderBird 1.2GHz SocketA BOX \28,770 faith MEMORY PC-133 128MB SDRAM CL3 \4,570 faith OS WindowsMe OEM版 \12,700 faith HDD Fujitsu MPG3409AT-E 流体軸受けタイプ40G \12,570 faith FDD 松下 JU-257A/ 2モードFDD \1,570 faith CDRW/DVD RICOH RW9120A OEM +B's Recorder Gold \27,700 faith +PowerDVD VR-X VGA HIS GeForce256 AGP 32MB リテール \6,970 faith CRT 飯山電機 A705MKIT(WirelessKey,Mouse付) \29,680 pc-park 送料 \2,200 faith -----------
バックラッシュのあとの数字は価格で空白のあとの文字列は店名です。 ここまで書いたら『あこれはシェルにやらせてみよう。』と思うのが 人情というものです。viを日本語対応にしたelvisというエディタを使って スクリプトを書いてみました。
% elvis mistumori.sh #!/bin/sh cat $1 cat $1 | awk -F \\ '{print $2}' | tr -d , | awk '{ s = s + $1 } END { printf"%43s,%5d,%03d\n","小計",s / 1000,s % 1000 } END { printf"%43s,%5d,%03d\n","消費税",s * 0.05 / 1000,s * 0.05 % 1000 } END { printf"%43s,%5d,%03d\n","合計",s * 1.05 / 1000,s * 1.05 % 1000 }' % chmod +x mistumori.sh % ./mistumori.sh mistumori.txt CASE MaxPoint CS-658QX 300W電源 Pentium4対応 \8,980 faith MB ECS K7VZA v3.0 KT133A(266mhzCPU対応) \10,970 faith CPU K7 Athlon ThunderBird 1.2GHz SocketA BOX \28,770 faith MEMORY PC-133 128MB SDRAM CL3 \4,570 faith OS WindowsMe OEM版 \12,700 faith HDD Fujitsu MPG3409AT-E 流体軸受けタイプ40G \12,570 faith FDD 松下 JU-257A/ 2モードFDD \1,570 faith CDRW/DVD RICOH RW9120A OEM +B's Recorder Gold \27,700 faith +PowerDVD VR-X VGA HIS GeForce256 AGP 32MB リテール \6,970 faith CRT 飯山電機 A705MKIT(WirelessKey,Mouse付) \29,680 pc-park 送料 \2,200 faith ----------- 小計, 146,680 消費税, 7,334 合計, 154,014
それではスクリプトの説明をします。cat $1 の $1 は コマンドmistumori.sh の 第一引数で mistumori.txt のことです。このようにシェルは $1 を第一引数 $2 を第二引数 $3 を第三引数 というように置換えします。またコマンドmistumori.shは $0 で置換えされ、 引数の数は $# で置き換えます。
% elvis hikisu.sh #!/bin/sh echo 'コマンド' $0 echo '第一引数' $1 echo '第二引数' $2 echo '第三引数' $3 echo '第四引数' $4 echo '第五引数' $5 echo '第六引数' $6 echo '第七引数' $7 echo '第八引数' $8 echo '第九引数' $9 echo '引数の数' $#
このようなファイルを作り chmod +x で実行権を与えます。
% ./hikisu.sh '蛇' '馬' '羊' '猿' '鳥' '犬' '猪' '鼠' '牛' コマンド ./hikisu.sh 第一引数 蛇 第二引数 馬 第三引数 羊 第四引数 猿 第五引数 鳥 第六引数 犬 第七引数 猪 第八引数 鼠 第九引数 牛 引数の数 9
置換えできるのは9番目の引数までです。次に cat $1 の標準出力をパイプを通して awk -F \\ '{ print $2 }' に渡しています。-F はフィールドセパレータを\ バックスラッシュにしていします。\は意味のある記号なので\を前に付けて\自体を あらわします。Windowsからは\バックスラッシュは円マークに表示されます。
% cat mistumori.txt | awk -F \\ '{ print $2 }' 8,980 faith 10,970 faith 28,770 faith 4,570 faith 12,700 faith 12,570 faith 1,570 faith 27,700 faith 6,970 faith 29,680 pc-park 2,200 faith
セパレータを \ とすると mistumori.txt は \ の前と後ろの二つに分けることができます。 この後ろの部分を取り出すために awk -F \\ '{ print $2 }' の print $2 の部分です。 print $1 とすると前の部分が取り出されます。このように $1 は一番目の列 $2 は 二番目の列 $3 は三番目の列というふうに取り出すことができます。$0は全体を 取り出すことができます。セパレータの指定がないときは空白をセパレータとします。 次に tr -d , として , コンマを取り除きます。tr は置換えコマンドでDOSの改行 コードをUNIXの改行コードに変えたいときに重宝されるコマンドです。くわしくは こちら
% cat mistumori.txt | awk -F \\ '{ print $2 }' | tr -d , 8980 faith 10970 faith 28770 faith 4570 faith 12700 faith 12570 faith 1570 faith 27700 faith 6970 faith 29680 pc-park 2200 faith
次にこの第一列目の数を awk で計算します。
% cat mistumori.txt | awk -F \\ '{ print $2 }' | tr -d , | awk ' { s = s + $1 } \ END { print s }' 146680
awk '{ s = s + $1 } END { print s }' で第一列目の数の合計を求めることが できます。s = s + $1 は s += $1 のように書くこともできます。\はコマンドが 長いために二行にするためです。今回のスクリプトでは printf で書式設定を しています。expr では小数点の計算はできませんが awk はできます。 s % 1000 の % は割った余りを求めるものです。printfで書式設定をする場合 書式の区切りには , コンマが付きます。このプログラムはバグありで awk -F \\ '{ print $2 }' で \ をセパレータとしていますが前半の文字列に よってうまく働かない時があるので注意が必要です。
``キーボード''の``ボ''があるとダメです。
awkの名前は Alfred V. Aho, Peter J. Weinberger, Brian W. Kernighan ら三人の 開発者の名前からきています。awkのオリジナルバージョンは1977年に AT&Tベル研究所 で書かれたそうです。