tar
tar
前回はstatなんてコマンドを調べた。ファイルのメタ情報(管理情報)を表示する奴。lsコ マンドのいわば親分だ。このメタ情報と普通にファイルの読み書きを組み合わ せれば、普段はDiskの中に鎮座してるファイルを外に保存できる事になる。
外に保存で一番利用してるのは、tarコマンド。調べてみる。
ob$ echo I am file of text >aa.txt ob$ echo '(define myname sakae)' >my.scm ob$ tar cf test.tar my.scm /tmp/aa.txt tar: Removing leading / from absolute path names in the archive ob$ tar tvf test.tar -rw-r--r-- 1 sakae wheel 22 May 13 06:45 my.scm -rw-r--r-- 1 sakae wheel 18 May 13 06:43 tmp/aa.txt
適当にファイルを2個作成し、それをtarコマンドでtest.tarにアーカイブして みた。そして、そのリストを確認。続いて、その内容をダンプしてみた。
ob$ hexdump -C test.tar 00000000 6d 79 2e 73 63 6d 00 00 00 00 00 00 00 00 00 00 |my.scm..........| 00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| * 00000060 00 00 00 00 30 31 30 30 36 34 34 00 30 30 30 31 |....0100644.0001| 00000070 37 35 30 00 30 30 30 30 30 30 30 00 30 30 30 30 |750.0000000.0000| 00000080 30 30 30 30 30 32 36 00 31 34 36 32 30 32 33 34 |0000026.14620234| 00000090 31 35 34 00 30 30 31 31 32 30 34 00 30 00 00 00 |154.0011204.0...| 000000a0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| * 00000100 00 75 73 74 61 72 00 30 30 73 61 6b 61 65 00 00 |.ustar.00sakae..| 00000110 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000120 00 00 00 00 00 00 00 00 00 77 68 65 65 6c 00 00 |.........wheel..| 00000130 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| * 00000200 28 64 65 66 69 6e 65 20 6d 79 6e 61 6d 65 20 73 |(define myname s| 00000210 61 6b 61 65 29 0a 00 00 00 00 00 00 00 00 00 00 |akae)...........| 00000220 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| * 00000400 74 6d 70 2f 61 61 2e 74 78 74 00 00 00 00 00 00 |tmp/aa.txt......| 00000410 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| : 00000600 49 20 61 6d 20 66 69 6c 65 20 6f 66 20 74 65 78 |I am file of tex| 00000610 74 0a 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |t...............| 00000620 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| * 00002800
何となく、ファイル名、(ファイルの)管理情報、ファイルのコンテンツの順に格納されてい る事が分かる。尚、'*' は、すぐ上の行と同じ物が続いている場合の省略を表 わしている(hexdumpの仕様)。
どうでもいい事だけど、my.scmに間違いがあった。
scheme@(guile-user)> (define myname sakae) Unbound variable: sakae scheme@(guile-user) [1]> (define myname 'sakae) scheme@(guile-user) [1]> myname $1 = sakae scheme@(guile-user) [1]> (symbol? $1) $2 = #t
シングルクォートを使って、評価を止めないと、sakae変数を利用しようとし て、そんな変数無いぞエラーに陥いる。
tarの作法
下記は、OpenBSDのマニュアルの冒頭部分
NAME tar - tape archiver SYNOPSIS tar {crtux}[014578befHhjLmNOoPpqsvwXZz] [blocking-factor | archive | replstr] [-C directory] [-I file] [file ...] tar {-crtux} [-014578eHhjLmNOoPpqvwXZz] [-b blocking-factor] [-C directory] [-f archive] [-I file] [-s replstr] [file ...]
保存先のデフォルトとしてテープ装置が仮定されている。巨大・膨大なファイ ルを何なく保存するのには磁気テープが適しているからね。でもまあ、個人で テープ装置を所有してる人なんて、まれだろうし、アクセスするにも、テープ の先頭から読んでいかないといけないという不自由さがある。
で、fと言う引数に続いて、ファイル名を指定できる事になっている。このファ イルを別なDiskとかUSB等に指定すれば、即席でバックアップ出来ることになる。
引数を指定する場合のUnixの習慣は、'-' で始める事なんだけど、無しでもか まわない。そう、gitに多数のサブコマンド(ex: clone,log,diff…)が有るけ ど、それの元祖みたいなものだ。だから、オイラーは tar -c .. みたいには しないのさ(そう言えば、psコマンドも、その主義だったな)。
c Create new archive t List contents of archive x Extract files from archive
あたりが、良く使うサブコマンドかな。一文字ってのが、いかにもUnixって事 で、すがすがしいぞ。
ob$ tar c my.scm tar: Failed open to write on /dev/rst0: Device not configured
貧乏人は、テープ装置なんて所有してないんで、割り当てなんて、もっての他 です。
tar c
少し動作を追跡。まずは作成モードから。
ob$ gdb -q tar Reading symbols from tar... (gdb) b main Breakpoint 1 at 0x1d627: file pax.c, line 228. (gdb) r cf test.tar aa.txt my.scm Breakpoint 1, main (argc=5, argv=0xcf7dfc94) at pax.c:228 228 listf = stderr; (gdb) b open Breakpoint 2 at 0x3b96e6b: file /usr/src/lib/libc/sys/w_open.c, line 29. (gdb) bt #0 _libc_open_cancel (path=0xcf7dfd50 "test.tar", flags=1537) at /usr/src/lib/libc/sys/w_open.c:29 #1 0x15b1ad0f in ar_open (name=0xcf7dfd50 "test.tar") at ar_io.c:123 #2 0x15b20af1 in wr_start () at buf_subs.c:114 #3 0x15b1fea3 in archive () at ar_subs.c:729 #4 0x15b2fa4e in main (argc=5, argv=0xcf7dfc94) at pax.c:314
Breakpoint 2, _libc_open_cancel (path=0x6ccea500 "aa.txt", flags=0) at /usr/src/lib/libc/sys/w_open.c:29 29 if (flags & O_CREAT) { (gdb) bt #0 _libc_open_cancel (path=0x6ccea500 "aa.txt", flags=0) at /usr/src/lib/libc/sys/w_open.c:29 #1 0x15b1f9cf in wr_archive (arcn=0xcf7de380, is_app=0) at ar_subs.c:468 #2 0x15b1feee in archive () at ar_subs.c:734 #3 0x15b2fa4e in main (argc=5, argv=0xcf7dfc94) at pax.c:314
この例では省略しちゃったけれど、/etc/group,/etc/pwd.dbも使ってた。グルー プ名とユーザー名の埋め込みに必要なんだろうね。それはそうと、lstatにBP を置いてもヒットしてこないぞ。なぜだ?
ここで、ちとソースを参照。関係有りそうな所にBP
Breakpoint 1, ustar_wr (arcn=0xcf7c2360) at tar.c:1391 1391 return wr_ustar_or_pax(arcn, 1); (gdb) bt #0 ustar_wr (arcn=0xcf7c2360) at tar.c:1391 #1 0x1442ee75 in wr_archive (arcn=0xcf7c2360, is_app=0) at ar_subs.c:500 #2 0x1442f22e in archive () at ar_subs.c:734 #3 0x1443ed8e in main (argc=5, argv=0xcf7c3cb4) at pax.c:314
(gdb) p *arcn $2 = {nlen = 6, name = "my.scm", '\000' <repeats 3066 times>, ln_nlen = 0, ln_name = '\000' <repeats 1960 times>..., org_name = 0x6a680a00 "my.scm", pat = 0x1447e96f <_libc_getpagesize+15>, sb = {st_mode = 33188, st_dev = 65280, st_ino = 90049, st_nlink = 1, st_uid = 1000, st_gid = 0, st_rdev = 360377, st_atim = {tv_sec = 1715641887, tv_nsec = 627223589}, st_mtim = {tv_sec = 1715550316, tv_nsec = 0}, st_ctim = { tv_sec = 1715632743, tv_nsec = 617223334}, st_size = 22, st_blocks = 2, st_blksize = 8192, st_flags = 0, st_gen = 0, __st_birthtim = {tv_sec = 0, tv_nsec = 0}}, pad = 0, skip = 22, crc = 876706524, type = 4}
実際にstatしてるのは、この中。fstatが利用されてた。ちゃんとmanして関連 品を炙り出しておけばよかった。まだまだ未熟だな。
(gdb) bt #0 ar_open (name=0xcf7e2248 "test.tar") at ar_io.c:157 #1 0x1b1b3e31 in wr_start () at buf_subs.c:114 #2 0x1b1b31e3 in archive () at ar_subs.c:729 #3 0x1b1c2d8e in main (argc=5, argv=0xcf7e2184) at pax.c:314
んで、大事な構造は下記だ。
pax.h
typedef struct { int nlen; /* file name length */ char name[PAXPATHLEN+1]; /* file name */ int ln_nlen; /* link name length */ char ln_name[PAXPATHLEN+1]; /* name to link to (if any) */ char *org_name; /* orig name in file system */ PATTERN *pat; /* ptr to pattern match (if any) */ struct stat sb; /* stat buffer see stat(2) */ off_t pad; /* bytes of padding after file xfer */ off_t skip; /* bytes of real data after header */ /* IMPORTANT. The st_size field does */ /* not always indicate the amount of */ /* data following the header. */ u_int32_t crc; /* file crc */ int type; /* type of file node */ #define PAX_DIR 1 /* directory */ #define PAX_CHR 2 /* character device */ #define PAX_BLK 3 /* block device */ #define PAX_REG 4 /* regular file */ #define PAX_SLK 5 /* symbolic link */ #define PAX_SCK 6 /* socket */ #define PAX_FIF 7 /* fifo */ #define PAX_HLK 8 /* hard link */ #define PAX_HRG 9 /* hard link to a regular file */ #define PAX_CTG 10 /* high performance file */ #define PAX_GLL 11 /* GNU long symlink */ #define PAX_GLF 12 /* GNU long file */ } ARCHD;
どうもtarファイルに出力する、各ファイルのメタ情報は、オクタル形式になってる。8進数を好んで使うって時代がかっているな。と 思ったら、manの歴史項目に
HISTORY A tar command first appeared in Version 7 AT&T UNIX.
開発されたのは、PDP-11とかのミニコンの時代なんですなあ。あの頃は、8進数が良く利用され てたって時代背景が有るのでしょう。歳のせいか、歴史物が好きであります。
tar x
展開ルーチンもザックリ見ておく。
(gdb) bt #0 file_creat (arcn=0xcf7d01d4) at file_subs.c:72 #1 0x1b7ce066 in extract () at ar_subs.c:321 #2 0x1b7ded81 in main (argc=3, argv=0xcf7d1b34) at pax.c:311 (gdb) bt #0 file_write (fd=8, str=0x3b7bb6d0 <bufmem+1024> "(define myname sakae)\n", cnt=22, rem=0xcf7d0168, isempt=0xcf7d016c, sz=8192, name=0xcf7d01d8 "my.scm") at file_subs.c:924 #1 0x1b7d1828 in rd_wrfile (arcn=0xcf7d01d4, ofd=8, left=0xcf7d01c8) at buf_subs.c:703 #2 0x1b7ce0dc in extract () at ar_subs.c:330 #3 0x1b7ded81 in main (argc=3, argv=0xcf7d1b34) at pax.c:311
ファイルを作成してから、書き込みなんだな。
(gdb) bt #0 fset_ftime (fnm=0xcf7d01d8 "my.scm", fd=8, mtimp=0xcf7d1a18, atimp=0xcf7d1a0c, frc=0) at file_subs.c:730 #1 0x1b7d535c in file_close (arcn=0xcf7d01d4, fd=8) at file_subs.c:153 #2 0x1b7ce0f8 in extract () at ar_subs.c:331 #3 0x1b7ded81 in main (argc=3, argv=0xcf7d1b34) at pax.c:311
アクセス時刻は、ファイルをクローズする直前に更新するのが上等(常套)手段。
tar size
これ、普通に作成したtarファイルのサイズ。
ob$ ls -l test.tar -rw-r--r-- 1 sakae wheel 10240 May 17 06:14 test.tar
作成時にbオプションを与えると、サイズが変わる。
ob$ tar cbf 10 test.tar aa.txt my.scm ob$ ls -l test.tar -rw-r--r-- 1 sakae wheel 5120 May 17 06:22 test.tar
こんな説明が有った。
-b blocking-factor Set blocking factor to use for the archive. tar uses 512-byte blocks. The default is 20, the maximum is 126. Archives with a blocking factor larger than 63 violate the POSIX standard and will not be portable to all systems.
デフォルトでは、このファクターが20なんで、512 x 20 = 10240 になるって 寸法。多分テープ装置には、これぐらいのブロック・サイズが好都合なんだろ うね。まあ、tarファイルそのままで作る事は無くて圧縮しちゃうんで、余り 関係ないけど。
ar_io.c
ar_start_gzip(int fd, const char *path, int wr) { zpid = fork(); /* parent */ if (zpid) { : } else { if (wr) { dup2(fds[0], STDIN_FILENO); dup2(fd, STDOUT_FILENO); gzip_flags = "-c"; } else { dup2(fds[1], STDOUT_FILENO); dup2(fd, STDIN_FILENO); gzip_flags = "-dc"; } putenv("PATH=/usr/bin:/usr/local/bin"); if (execlp(path, path, gzip_flags, (char *)NULL) == -1)
ってな具合に圧縮と伸長は、tarとは独立した機構に依存してます。そこん所 が、Windowsの標準になってる、zip とは、大違いなのさ。
cpio + tar -> pax ??
そもそも、cpioなんてコマンドを知ったのは、OpenBSDのtarソースを探してい た時。tarの配置は、/bin/tar だった。ならば、/usr/src/bin/tar が有って しかるべき。でも、そんなの無い。で、うろうろしてて、pax群に辿りついた 次第。
POSIXの大失敗 〜 cpio vs tar戦争を平和に導くためにpaxコマンドを作った結果
アーカイブ – TAR と CPIO のアーカイブファイル形式の違いは何ですか?
余り使う事は無いだろうけど、cpioをためしてみる。
ob$ ls aa.txt my.scm >list ob$ cpio -o < list >OUT
そしてダンプ
ob$ hexdump -C OUT 00000000 30 37 30 37 30 32 30 30 30 30 39 36 63 31 30 30 |070702000096c100| 00000010 30 30 38 31 61 34 30 30 30 30 30 33 65 38 30 30 |0081a4000003e800| 00000020 30 30 30 30 30 30 30 30 30 30 30 30 30 31 36 36 |0000000000000166| 00000030 34 31 33 38 30 37 30 30 30 30 30 30 31 32 30 30 |4138070000001200| 00000040 30 30 30 30 66 66 30 30 30 30 30 30 30 30 30 30 |0000ff0000000000| 00000050 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 |0000000000000000| 00000060 30 30 30 30 30 37 30 30 30 30 30 35 64 62 61 61 |000007000005dbaa| 00000070 2e 74 78 74 00 00 00 00 49 20 61 6d 20 66 69 6c |.txt....I am fil| 00000080 65 20 6f 66 20 74 65 78 74 0a 00 00 30 37 30 37 |e of text...0707| 00000090 30 32 30 30 30 30 30 30 30 34 30 30 30 30 38 31 |0200000004000081| 000000a0 61 34 30 30 30 30 30 33 65 38 30 30 30 30 30 30 |a4000003e8000000| 000000b0 30 30 30 30 30 30 30 30 30 31 36 36 34 33 63 65 |00000000016643ce| 000000c0 36 64 30 30 30 30 30 30 31 37 30 30 30 30 30 30 |6d00000017000000| 000000d0 66 66 30 30 30 30 30 30 30 30 30 30 30 30 30 30 |ff00000000000000| 000000e0 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 |0000000000000000| 000000f0 30 37 30 30 30 30 30 37 62 39 6d 79 2e 73 63 6d |07000007b9my.scm| 00000100 00 00 00 00 28 64 65 66 69 6e 65 20 6d 79 6e 61 |....(define myna| 00000110 6d 65 20 27 73 61 6b 61 65 29 0a 00 30 37 30 37 |me 'sakae)..0707| 00000120 30 32 30 30 30 30 30 30 30 30 30 30 30 30 30 30 |0200000000000000| 00000130 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 |0000000000000000| 00000140 30 30 30 30 30 30 30 30 30 31 30 30 30 30 30 30 |0000000001000000| 00000150 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 |0000000000000000| * 00000180 30 62 30 30 30 30 30 30 30 30 54 52 41 49 4c 45 |0b00000000TRAILE| 00000190 52 21 21 21 00 00 00 00 00 00 00 00 00 00 00 00 |R!!!............| 000001a0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| * 00001400
展開してみる。
ob$ cpio -i <OUT ob$ stat -x aa.txt my.scm File: "aa.txt" Size: 18 FileType: Regular File Mode: (0644/-rw-r--r--) Uid: ( 1000/ sakae) Gid: ( 0/ wheel) Device: 255,0 Inode: 4 Links: 1 Access: Mon May 13 06:43:35 2024 Modify: Wed May 15 08:03:13 2024 Change: Wed May 15 08:03:13 2024 File: "my.scm" Size: 23 FileType: Regular File Mode: (0644/-rw-r--r--) Uid: ( 1000/ sakae) Gid: ( 0/ wheel) Device: 255,0 Inode: 6 Links: 1 Access: Wed May 15 05:49:49 2024 Modify: Wed May 15 08:03:13 2024 Change: Wed May 15 08:03:13 2024
paxの出番を探してみる。
ob$ pwd /usr/src/distrib/miniroot ob$ grep pax -r . ./install.sub: (cd /mnt/etc/skel; pax -rw -k -pe . $_home) ./list2sh.awk: printf("(cd %s && pax -pe -rw . ${TARGDIR}/%s)\n", $2, $3);
やっと見付けた。cpioは発見できず。なんかtarの一人勝ちだな。GNUのtar なんて、化け物みたいにオプションが増加してる。unixのシンプルさは、何処 へ行ってしまったのでしょう。
ar
tarみたいに、複数のファイルを一纏めにするコマンドが他にもある。パッと 思いつくのは、 ar - コマンド (プログラム) の説明
ob$ ar cru zz.a aa.txt my.scm ob$ hexdump -C zz.a 00000000 21 3c 61 72 63 68 3e 0a 61 61 2e 74 78 74 2f 20 |!<arch>.aa.txt/ | 00000010 20 20 20 20 20 20 20 20 30 20 20 20 20 20 20 20 | 0 | 00000020 20 20 20 20 30 20 20 20 20 20 30 20 20 20 20 20 | 0 0 | 00000030 36 34 34 20 20 20 20 20 31 38 20 20 20 20 20 20 |644 18 | 00000040 20 20 60 0a 49 20 61 6d 20 66 69 6c 65 20 6f 66 | `.I am file of| 00000050 20 74 65 78 74 0a 6d 79 2e 73 63 6d 2f 20 20 20 | text.my.scm/ | 00000060 20 20 20 20 20 20 30 20 20 20 20 20 20 20 20 20 | 0 | 00000070 20 20 30 20 20 20 20 20 30 20 20 20 20 20 36 34 | 0 0 64| 00000080 34 20 20 20 20 20 32 32 20 20 20 20 20 20 20 20 |4 22 | 00000090 60 0a 28 64 65 66 69 6e 65 20 6d 79 6e 61 6d 65 |`.(define myname| 000000a0 20 73 61 6b 61 65 29 0a | sakae).| 000000a8
これがarの基本的な利用方法。って、普通は、対象がコンパイル済みのオブジェ クト・ファイルなんだけどね。判り易い様に、あえて対象をテキスト・ファイ ルにしてみた次第。
普通は、
ob$ ar cr pax.a *.o ob$ ar tv pax.a rw-r--r-- 0/0 40932 Jan 1 09:00 1970 ar_io.o rw-r--r-- 0/0 33640 Jan 1 09:00 1970 ar_subs.o rw-r--r-- 0/0 26872 Jan 1 09:00 1970 buf_subs.o rw-r--r-- 0/0 30440 Jan 1 09:00 1970 cpio.o rw-r--r-- 0/0 31320 Jan 1 09:00 1970 file_subs.o rw-r--r-- 0/0 16968 Jan 1 09:00 1970 ftree.o rw-r--r-- 0/0 15152 Jan 1 09:00 1970 gen_subs.o rw-r--r-- 0/0 3384 Jan 1 09:00 1970 getoldopt.o rw-r--r-- 0/0 47668 Jan 1 09:00 1970 options.o rw-r--r-- 0/0 26440 Jan 1 09:00 1970 pat_rep.o rw-r--r-- 0/0 17788 Jan 1 09:00 1970 pax.o rw-r--r-- 0/0 16620 Jan 1 09:00 1970 sel_subs.o rw-r--r-- 0/0 39616 Jan 1 09:00 1970 tables.o rw-r--r-- 0/0 46828 Jan 1 09:00 1970 tar.o rw-r--r-- 0/0 7920 Jan 1 09:00 1970 tty_subs.o
こんな風にアーカイブ・ファイルを作成する。
ob$ cc -o tar pax.a ob$ cc -o cpio pax.a ob$ cc -o pax pax.a
一度アーカイブが出きれば、そこから実行ファイルを作成するのは、簡単。下 記は、作成した実行ファイルが、それらしく振舞うか、適当な引数を与えて (怒らせて)確認。
ob$ ./cpio ss usage: cpio -o [-AaBcjLvZz] [-C bytes] [-F archive] [-H format] [-O archive] < name-list [> archive] cpio -i [-6BbcdfjmrSstuvZz] [-C bytes] [-E file] [-F archive] [-H format] [-I archive] [pattern ...] [< archive] cpio -p [-adLlmuv] destination-directory < name-list ob$ ./pax -h pax: unknown option -- h usage: pax [-0cdjnOvz] [-E limit] [-f archive] [-G group] [-s replstr] [-T range] [-U user] [pattern ...] pax -r [-0cDdijknOuvYZz] [-E limit] [-f archive] [-G group] [-o options] [-p string] [-s replstr] [-T range] [-U user] [pattern ...] pax -w [-0adHijLOPtuvXz] [-B bytes] [-b blocksize] [-f archive] [-G group] [-o options] [-s replstr] [-T range] [-U user] [-x format] [file ...] pax -rw [-0DdHikLlnOPtuvXYZ] [-G group] [-p string] [-s replstr] [-T range] [-U user] [file ...] directory
どうやら、大丈夫そう。
ob$ ls -l cpio pax tar -rwxr-xr-x 1 sakae wheel 305028 May 16 07:34 cpio* -rwxr-xr-x 1 sakae wheel 305028 May 16 07:34 pax* -rwxr-xr-x 1 sakae wheel 305028 May 16 07:33 tar*
名前は異なるけど、生身は同一。だから、Makefile上では
LINKS= ${BINDIR}/pax ${BINDIR}/tar ${BINDIR}/pax ${BINDIR}/cpio
こんな風に、リンクを作れって指令になってるのさ。
arコマンドは色々な変遷を得ている。今は、llvm一族になってるんだけど、変 らずに、継承してる部分が、 ar.hに示されている。
struct ar_hdr { char ar_name[16]; /* name */ char ar_date[12]; /* modification time */ char ar_uid[6]; /* user id */ char ar_gid[6]; /* group id */ char ar_mode[8]; /* octal file permissions */ char ar_size[10]; /* size in bytes */ #define ARFMAG "`\n" char ar_fmag[2]; /* consistency check */ };
それはそうと、更新時刻が記録される様になってるのに、先程作ったアーカイ ブは、ことごとくunixの始祖の時刻になってた。利用方法が間違ってる? こういう時は、別OSで確認するのがよかろう。Debian/WSL2上のgauche
sakae@atom:/usr/local/lib$ ar tv libgauche-static-0.98.a | head -5 rw-r--r-- 0/0 23920 Jan 1 09:00 1970 box.o rw-r--r-- 0/0 87840 Jan 1 09:00 1970 core.o rw-r--r-- 0/0 628032 Jan 1 09:00 1970 vm.o rw-r--r-- 0/0 68896 Jan 1 09:00 1970 compaux.o rw-r--r-- 0/0 113048 Jan 1 09:00 1970 macro.o
Uum …
my.scmを変更した。それをアーカイブに反映してみる。
ob$ ar rU zz.a my.scm ob$ ar tv zz.a rw-r--r-- 0/0 18 Jan 1 09:00 1970 aa.txt rw-r--r-- 1000/0 23 May 17 06:10 2024 my.scm ob$ hexdump -C zz.a 00000000 21 3c 61 72 63 68 3e 0a 61 61 2e 74 78 74 2f 20 |!<arch>.aa.txt/ | 00000010 20 20 20 20 20 20 20 20 30 20 20 20 20 20 20 20 | 0 | 00000020 20 20 20 20 30 20 20 20 20 20 30 20 20 20 20 20 | 0 0 | 00000030 36 34 34 20 20 20 20 20 31 38 20 20 20 20 20 20 |644 18 | 00000040 20 20 60 0a 49 20 61 6d 20 66 69 6c 65 20 6f 66 | `.I am file of| 00000050 20 74 65 78 74 0a 6d 79 2e 73 63 6d 2f 20 20 20 | text.my.scm/ | 00000060 20 20 20 20 20 20 31 37 31 35 38 39 33 38 33 36 | 1715893836| 00000070 20 20 31 30 30 30 20 20 30 20 20 20 20 20 36 34 | 1000 0 64| 00000080 34 20 20 20 20 20 32 33 20 20 20 20 20 20 20 20 |4 23 | 00000090 60 0a 28 64 65 66 69 6e 65 20 6d 79 6e 61 6d 65 |`.(define myname| 000000a0 20 27 73 61 6b 61 65 29 0a 0a | 'sakae)..| 000000aa
今度は、ちゃんとファイル情報が反映された。
gauche
gaucheを実行する為の部品セットが用意されてるので、容易にgaucheを下敷に したアプリを生成できる。新たに準備する物は、main.c のみだ。 (paxの場合は、main()が既に定義されてオブジェクトファイルの一員になってたか ら、不要だった)
#include <stdio.h> #include <gauche.h> int main() { ScmObj p; ScmObj list; GC_INIT(); Scm_Init(GAUCHE_SIGNATURE); list = SCM_LIST3(SCM_MAKE_INT(1), SCM_MAKE_INT(2), SCM_MAKE_INT(3)); for(p = list; SCM_PAIRP(p); p = Scm_Cdr(p)) { printf("%ld\n", SCM_INT_VALUE(Scm_Car(p))); } return 0; }
(list 1 2 3)を作成して、それをスキャン出力する。
SRC = main.c OUT = a.out INCLUDE_DIR = `gauche-config -I` LIBRARY_DIR = `gauche-config -L` LIBRARIES = `gauche-config -l` $(OUT): $(SRC) gcc -std=gnu99 -Ofast -Wall -Werror -o $(OUT) $(INCLUDE_DIR) $^ $(LIBRARY_DIR) $(LIBRARIES) clean: rm -f $(OUT)
こちらはMakefile。正確には、上で参照したアーカイブを利用してないけど、 それに順ずるsoファイルをリンクしてる。xx.soとxx.aが存在した場合、xx.so を利用する様になってるからね。その方が、SDG'sだからね。
sakae@atom:/mnt/r$ make gcc -std=gnu99 -Ofast -Wall -Werror -o a.out `gauche-config -I` main.c `gauche-config -L` \ `gauche-config -l` sakae@atom:/mnt/r$ ./a.out 1 2 3
こんな風にコンパイルすれば、本体にアーカイブ・ファイルを取り込める。
gcc -std=gnu99 -Ofast -Wall -Werror -o my `gauche-config -I` main.c `gauche-config -L` \ /usr/local/lib/libgauche-static-0.98.a -lcrypt -lrt -lm -lpthread
gaucheの核になる部分で膨れたアプリになってしまう。こんなアプリが複数あっ たら、DISKエリアの無駄になるし、何より貴重なメモリーエリアも無駄使いし ちゃう可能性がある。SDG's的に、いかがなものかと思う昨今ですよ。
sakae@atom:/mnt/r$ ls -l a.out my -rwxrwxrwx 1 sakae sakae 17672 May 17 07:44 a.out* -rwxrwxrwx 1 sakae sakae 16678224 May 17 07:50 my*
ChatGPT
GPT-4o を紹介されたぞ。でも、オイラーは古い奴で十分。だって、古い事し か尋ねないから。
Q: Unix系のアーカイバーには、pax,cpio,tarが有ります。そのうちのtarだけが流通してるように見受けられます。その理由を説明してください。
A: Unix系のアーカイバーには、pax、cpio、tarが存在しますが、その中でもtarが広く普及し、一般的に使用されている理由について説明します。以下に、tarの普及の背景、技術的特徴、歴史的経緯、他のアーカイバーとの比較などを通じて、tarが主流となった理由を詳述します。
### 1. tarの技術的特徴と利便性
tar(tape archive)は、ファイルのアーカイブと復元を行うためのツールであり、特に以下の点で優れています。
- シンプルな構造: tarは一つのアーカイブファイルに複数のファイルやディレクトリをまとめて保存するためのシンプルな形式を採用しています。これにより、扱いやすく、データのバックアップや移行が簡単に行えます。
- 柔軟なオプション: tarは圧縮機能と組み合わせることで、多用途に使用できます。圧縮なしの単純なアーカイブ作成から、gzip(.tar.gz)やbzip2(.tar.bz2)を使用した圧縮アーカイブの作成まで、多様なニーズに応じた使い方が可能です。
- ポータビリティ: tarアーカイブは、Unix系システム間での互換性が高く、異なるシステム間でファイルをやり取りする際にも信頼性があります。これにより、多くのUnix系オペレーティングシステムで標準的に使用されています。
### 2. tarの歴史的背景
tarの歴史は非常に古く、1979年に最初に登場しました。UNIXの初期の時代から存在し、以下の点がtarの普及を後押ししました。
- 初期の標準ツール: tarは、UNIXの標準ツールの一部として採用され、多くのUnix系オペレーティングシステムに組み込まれていました。これにより、ユーザーは追加のインストールや学習を必要とせずにtarを利用できました。
- ソフトウェア配布のデファクトスタンダード: 多くのオープンソースプロジェクトや商用ソフトウェアは、tarを使用してソースコードやバイナリを配布していました。tarアーカイブを使用することで、開発者やユーザーはソフトウェアのインストールや配布を簡単に行うことができました。
### 3. 他のアーカイバーとの比較
#### pax
paxはPOSIX標準のアーカイブユーティリティであり、tarやcpioの両方の機能を統合しています。しかし、paxがtarほど普及しなかった理由には以下の点が挙げられます。
- 後発のツール: paxはtarやcpioに比べて後発のツールであり、既に普及していたtarを置き換えることは難しかった。
- 複雑さ: tarやcpioに比べてオプションや機能が多く、一般ユーザーにはやや複雑に感じられることがありました。
#### cpio
cpioはtarと同様に古い歴史を持つアーカイバーですが、普及しなかった理由には以下の点があります。
- インターフェースの違い: cpioは、tarと異なり標準入力からファイルリストを読み込むという独特の方法を採用しています。これがユーザーにとってやや直感的ではなく、扱いにくいと感じられることがありました。
- 圧縮オプションの限定: cpio自体には圧縮機能がなく、別途圧縮ツールと組み合わせて使用する必要があります。この点で、圧縮オプションを直接サポートするtarの方が利便性が高いと評価されました。
### 4. tarのエコシステムとコミュニティサポート
tarが広く普及し、標準的なツールとして定着した背景には、エコシステムやコミュニティのサポートも大きな役割を果たしています。
- ドキュメントとチュートリアルの豊富さ: tarは広く使用されているため、ドキュメントやチュートリアルが豊富に存在します。これにより、新規ユーザーでも学習コストが低く、簡単に利用を始めることができます。
- ツールとの統合: tarは、makeやconfigureなどのビルドツールと統合されており、ソフトウェアのビルドプロセスにおいても重要な役割を果たしています。このような統合によって、tarの使用がさらに促進されました。
- オープンソースコミュニティのサポート: オープンソースプロジェクトの多くがtarを公式のアーカイブフォーマットとして採用しており、コミュニティ全体でのサポートが強力です。これにより、tarは信頼性が高く、長期間にわたり使用され続けています。
### 結論
tarがUnix系アーカイバーの中で広く普及し、主流となっている理由は、そのシンプルな構造と柔軟なオプション、歴史的背景、他のアーカイバーと比較しての利便性、そしてエコシステムとコミュニティの強力なサポートにあります。これらの要素が組み合わさることで、tarは長年にわたり信頼され続け、多くのユーザーに利用されています。