     [file version.texi not included]
     [file constants.texi not included]

GNU Coreutils
*************

このマニュアルは、GNU core utilities version VERSION の詳細な解説である。 core utilities には、テキストやファイルを操作するための標準的なプログラムが入っている。

Copyright © 1994-2016 Free Software Foundation, Inc.

Japanese translation copyright © 2014-2017 Linux JM project

     Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.3 or any later version published by the Free Software Foundation; with no Invariant Sections, with no Front-Cover Texts, and with no Back-Cover Texts.  A copy of the license is included in the section entitled ``GNU Free Documentation License''.

【訳者から御注意】 この文書を info コマンドで閲覧なさっている場合は、行末に余計な文字が入って、読みにくいことがあるかもしれない。そうしたときは、Ctrl キーと l (エル) キーを同時に押して、画面を再描画していただきたい。たぶん、表示が正常になるはずである。

お手元の coreutils のバージョンが VERSION 以外の場合、この文書の説明と動作が違うことがあるかもしれない (たとえば、この文書に書いてあるオプションが使えない、あるいは、使えるはずのオプションの説明がないなど)。そうした場合は、お使いの coreutils と同じバージョンの info マニュアルや man ページに当ってみていただきたい。そちらの方が正しいはずである。

序
*

このマニュアルは作成の途上にある。たとえば、多くのセクションで、基本的な概念を初心者にわかりやすく説明するといった試みがなされていない。そこで、お願いがある。もし、関心がおありなら、このマニュアルの改良に参加していただきたい。そうしていただければ、GNU コミュニティ全体が恩恵に浴することになる。

このマニュアルで解説している GNU ユーティリティは、 POSIX の規格におおむね準拠している。

バグの報告は、bug-coreutils@gnu.org になさっていただきたい。そのとき、プログラムのバージョン番号、マシンのアーキテクチャ、入力に使ったファイルといった情報はもとより、バグの再現に必要な他のいかなる情報も、記載していただきたい。たとえば、どんな入力をしたか、どんな結果を期待していたか、実際の結果はどうだったか、それがおかしいと考える理由は何なのかといったことである。

sort や date コマンドの動作に疑問がある場合は、--debug オプションを試してみていただきたい。その出力が手がかりになって、バグレポートに対する回答を待つまでもなく、問題の在り処を突き止め、解決できることも多いからだ。デバッグの出力が問題を自分で解決するのに十分でないときは、それを圧縮して、提出するバグレポートに添付していただきたい。

差分の投稿は歓迎するが、何がどう問題なのかの説明もやはり付けていただきたい。推測するのが難しいこともあるからだ。 See Bugs (Using and Porting GNU CC).

このマニュアルは、ユーティリティ・プログラムの配布に含まれる Unix man page を元にして作られたものである。そうした man page は、David MacKenzie によって書かれ、Jim Meyering によって改訂されていた。現在読者がお読みになっているこのマニュアルは、そうしたユーティリティについての公式文書であり、 man page の方は、今では改訂作業が行われていない。なお、fmt の最初の man page の著者は、Ross Paterson だった。 Texinfo 形式への変換を最初に行ったのは、François Pinard である。 Karl Berry が索引を作成し、構成に若干の変更を加えて、その結果に手を入れた。 Free Software Foundation の職員である Brian Youman が textutils, fileutils, sh-utils のマニュアルを統合し、多数の項目を含む現在のマニュアルを作成した。こうした作業全般に渡って、 Richard Stallman が例によって洞察力に富む貴重な意見を寄せてくれた。

共通オプション
*******

いくつかのオプションは、このマニュアルで取り上げるすべてのプログラムで利用することができる。そうしたオプションについては、個々のプログラムで同じ説明を繰り返すことはせず、この場で説明しておく (実のところ、そうしたオプションは、GNU のすべてのプログラムで使用できる (はずである))。

通常、オプションとオペランドは、どんな順番で指定してもよい。プログラムは、すべてのオプションがいかなるオペランドよりも前にあるかのごとく振る舞うようになっている。たとえば、sort -r passwd -t : は、: が -t のオプション引数 (option-argument) なので、sort -r -t : passwd と同じ動作をする。しかしながら、環境変数 POSIXLY_CORRECT が設定されている場合は、オプションはオペランドの前に置かなければならない。ただし、オプションとオペランドの順番について、そのコマンドに別の決まりがあるときはこのかぎりではない。

若干のプログラムでは、二番目以降のオペランドとして先頭に - が付くオペランドが使えると都合がよい。そうしたプログラムでは、POSIXLY_CORRECT が設定されていない場合でも、オプションをオペランドの前に置く必要がある。そこで、そうしたプログラムの説明には、その旨注意書きを付けておいた。たとえば、env コマンドのオプションは、オペランドの前に置かなければならない。オペランドとして指定したコマンドが、それ自身のオプションを伴うことがあるからだ。

ロングオプションが使えるたいていのプログラムは、誤解の余地がないかぎり、そうしたオプションの省略形を認識する。たとえば、rmdir --ignore-fail-on-non-empty は、rmdir --ignore-fail という形でも起動できるし、rmdir --i でも大丈夫だ。 ls --h のような誤解の余地のあるオプションは、まさに曖昧だと判定される。

このマニュアルで説明するプログラムの中には、--help や --version オプションを、それが唯一のコマンドライン引数である場合にしか、認識しないものがある。そうしたプログラムの場合、ロングオプションの省略形は、常に認識されるとはかぎらない。

--help
     使用法を表示して利用できるすべてのオプションを列挙し、正常終了する。

--version
     バージョン番号を表示し、正常終了する。

--
     オプション群の末尾を示す。これ以降に引数があれば、それが - で始まっている場合でも、オペランドとして扱われる。たとえば、sort -- -r は、-r という名前のファイルから読み込むということである。

単独の - はオペランドであって、オプションのように見えるが、オプションでは全くない。単独の - はファイル・オペランドであり、プログラム次第で、標準入力、あるいは標準出力として扱われる。後者は、前後の状況からそれが明らかな場合だ。たとえば、sort - は、標準入力から読み込むということであり、ただの sort と同じである。使用できないとはっきり断っていないかぎり、- は、ファイル名が要求されるいかなるところでもオペランドとして使用することができる。

終了ステータス
=======

ほとんどすべてのコマンドは、実行すると、整数の終了ステータス (exit status) を返し、それは他のコマンドの動作を変更するために使用することができる。大多数のコマンドにとって、終了ステータス 0 は成功を意味している。失敗は 0 以外の値によって示され、たいていは 1 だが、非標準的なプラットフォームでは違うこともある。POSIX の規定が、0 以外であることしか要求していないからである。

しかしながら、ここで詳述しているプログラムの中にも、終了ステータスとして上記以外の値を返すものがあり、 0 や 1 という値に別の意味を与えているプログラムさえ、少数ながら存在する。そうした例外的なプログラムとしては、chroot, env, expr, nice, nohup, numfmt, printenv, sort, stdbuf, test, timeout, tty などを挙げることができる。

バックアップ・オプション
============

GNU のプログラムの中には、ファイルの新しいバージョンを書き出す前に、もしそうしたければ、バックアップを作成できるものがある (少なくとも cp, install, ln, mv がそうだ)。下記のオプションは、そうしたバックアップを細かく制御する。こうしたオプションについては、個々のプログラムの説明でも簡単に触れている。

-b
--backup[=METHOD]
     通常では上書きされたり、消去されたりする各ファイルのバックアップを作成する。このオプションを指定しないと、元のバージョンは破棄されるわけだ。作成するバックアップのタイプを決めるには、METHOD を使用する。 METHOD を指定せずに、このオプションを使った場合は、環境変数 VERSION_CONTROL の値が使用される。VERSION_CONTROL が設定されていない場合、デフォルトのバックアップタイプは existing である。

     このオプションの短縮形である -b は、引数を取らないことに注意していただきたい。 -b の使用は、--backup=existing を使用するのと同じことである。

     このオプションは、Emacs の version-control 変数に対応している。すなわち、METHOD に指定する値は、Emacs で使用される値と同じものである。とは言え、このオプションでは、より説明的な名前も使用できる。 METHOD の有効な値は、以下のものである (他と区別できるならば、省略した表現も使用できる)。

     none
     off
          バックアップを作成しない。

     numbered
     t
          どんな場合でも番号付きのバックアップを作成する。

     existing
     nil
          番号付きのバックアップがすでに存在する場合は番号付きで、それ以外の場合は単純形式で、ファイルのバックアップを作成する。 (訳注: 単純形式というのは、バックアップファイル名に番号を付けない形式である。 --suffix=SUFFIX の説明を参照。)

     simple
     never
          どんな場合でも単純形式のバックアップを作成する。never と none を混同なさらないようにしていただきたい。

-S SUFFIX
--suffix=SUFFIX
     -b で作成される各バックアップファイルの名前の末尾に SUFFIX を付ける。このオプションが指定されていない場合は、環境変数 SIMPLE_BACKUP_SUFFIX の値が使用される。SIMPLE_BACKUP_SUFFIX が設定されていない場合、デフォルトの SUFFIX は Emacs の場合と同じで、チルダ ~ である。

ブロックサイズ
=======

GNU プログラムには、ディスクの使用量を「ブロック数」で表示するものがいくつかある (少なくとも、df, du,ls がそうだ)。ブロックのサイズや表示の書式は、使用量をわかりやすくするために、変更することができる。表示に使用されるブロックサイズは、ファイルシステムのブロックサイズとは、無関係である。ブロック数に端数が出る場合は、切り上げて整数にする。

デフォルトのブロックサイズの選択は、次の環境変数を順番に調べることで行われる。設定されている最初のものがブロックサイズを決めることになる。

DF_BLOCK_SIZE
     この環境変数は、df コマンドで使うデフォルトのブロックサイズを指定している。同様に、DU_BLOCK_SIZE は du のデフォルトを、 LS_BLOCK_SIZE は ls のデフォルトを指定している。

BLOCK_SIZE
     この環境変数は、上記のようなコマンド専用の環境変数が設定されていない場合に、三つのコマンドのすべてが使用するデフォルトのブロックサイズを指定している。

BLOCKSIZE
     この環境変数は、上記のようなコマンド専用の環境変数と BLOCK_SIZE のどちらも設定されていない場合に、通常、ブロック数として表示されるすべての値が使用するデフォルトのブロックサイズを指定している。ほかの環境変数とは違って、BLOCKSIZE は、たとえば ls -l の出力に含まれるファイルサイズのような、通常バイト数として表示される値には影響を及ぼさない。

POSIXLY_CORRECT
     COMMAND_BLOCK_SIZE, BLOCK_SIZE, BLOCKSIZE のいづれも設定されていず、この変数が設定されている場合は、ブロックサイズのデフォルトは、512 バイトになる。

上記の環境変数のいづれも設定されていない場合、ブロックサイズのデフォルトは、現在のところたいていの場合、 1024 バイトである。ただし、この数値は、将来変更されるかもしれない。なお、ls の表示するファイルサイズについては、ブロックサイズのデフォルトは 1 バイトである。

ブロックサイズの指定には、1 ブロックあたりのバイト数を示す正の整数を使えばよい。あるいは、human-readable や si を指定して、「人間に読みやすい」書式を選ぶこともできる。整数の後ろには接尾辞 (suffix) を続けてもよい。そうした接尾辞は、単位の前に付けて 10 の累乗倍を表す SI (国際単位系) の接頭辞 (prefix) や、 2 の累乗倍を表す ISO/IEC 80000-13 (以前は IEC 60027-2 だった) の接頭辞の上位互換である。単位の前に付ける接頭辞については、次の URL を参照していただきたい。

SI prefixes: (http://www.bipm.org/en/publications/si-brochure/chapter3.html). ISO/IEC 80000-13 prefixes: (http://physics.nist.gov/cuu/Units/binary.html).

「人間に読みやすい」書式の場合、出力するサイズの後ろに、メガバイトなら M といった、大きさを表す文字が続く。BLOCK_SIZE=human-readable の方は、1024 の累乗を使うので、M は 1,048,576 バイトを意味している。 BLOCK_SIZE=si も似ているが、こちらは 1000 の累乗を使用し、さらに B という文字を追加する。そこで、MB は 1,000,000 バイトを意味することになる。

ブロックサイズの指定の先頭に ' を付けると、出力するサイズを数桁ごとに区切って表示することができる。区切りに使う記号や区切りの位置は、LC_NUMERIC のロケールによって決まる。たとえば、アメリカ英語のロケールでは、--block-size="'1kB" と指定すれば、1234000 バイトという容量が 1,234 と表示されることになるだろう。デフォルトの C ロケールの場合は、区切り記号が存在しないので、先頭の ' に効果はない。

ブロックサイズを指定する整数の後ろには、接尾辞を付けて、その整数の何倍かを示すことができる。大きさを表す (訳注: M, G などの) 文字の後ろに何も続けないときや、iB を続けるときは、 1024 の累乗倍ということである。それに対して、大きさを表す文字に B を続ける場合は、1000 の累乗倍ということになる。たとえば、1M や 1MiB は 1048576 と同じであり、 1MB は 1000000 と同じである。

整数を前に付けずに、接尾辞だけを指定したときの動作は、 1 が前に付いているときとほぼ同じだが、大きさの表示が出力の後ろに付く点が違う。たとえば、--block-size="kB" は、3000 を 3kB という形で表示する。

以下の接尾辞が定義されている。1Y のような大きな量は、算術計算の限界のためにお使いのコンピュータでは使用できないかもしれない。

kB
     キロバイト (kilobyte): 10^3 = 1000 バイト。

k
K
KiB
     キビバイト (kibibyte): 2^10 = 1024 バイト。 K も使えるのは、おまけである。なお本来、SI の接頭辞 (訳注: すなわち 10^3 倍を表す接頭辞) が k であり、 ISO/IEC 80000-13 の接頭辞 (訳注: すなわち 2^10 倍を表す接頭辞) が Ki だが、これまでの習慣や POSIX の用法では、 KiB の意味で k を使っている。

MB
     メガバイト (megabyte): 10^6 = 1,000,000 バイト。

M
MiB
     メビバイト (mebibyte): 2^20 = 1,048,576 バイト。

GB
     ギガバイト (gigabyte): 10^9 = 1,000,000,000 バイト。

G
GiB
     ギビバイト (gibibyte): 2^30 = 1,073,741,824 バイト。

TB
     テラバイト (terabyte): 10^12 = 1,000,000,000,000 バイト。

T
TiB
     テビバイト (tebibyte): 2^40 = 1,099,511,627,776 バイト。

PB
     ペタバイト (petabyte): 10^15 = 1,000,000,000,000,000 バイト。

P
PiB
     ペビバイト (pebibyte): 2^50 = 1,125,899,906,842,624 バイト。

EB
     エクサバイト (exabyte): 10^18 = 1,000,000,000,000,000,000 バイト。

E
EiB
     エクスビバイト (exbibyte): 2^60 = 1,152,921,504,606,846,976 バイト。

ZB
     ゼタバイト (zettabyte): 10^21 = 1,000,000,000,000,000,000,000 バイト。

Z
ZiB
     ゼビバイト (zebibyte): 2^70 = 1,180,591,620,717,411,303,424 バイト。

YB
     ヨタバイト (yottabyte): 10^24 = 1,000,000,000,000,000,000,000,000 バイト。

Y
YiB
     ヨビバイト (yobibyte): 2^80 = 1,208,925,819,614,629,174,706,176 バイト。

デフォルトのブロックサイズは、コマンドに対して --block-size=SIZE オプションを明示的に指定することで、上書きすることができる。-k オプションは、--block-size=1K と同じであり、環境変数 POSIXLY_CORRECT が設定されていないときのデフォルトである。-h オプションや --human-readable オプションは、--block-size=human-readable と同じである。--si オプションは、--block-size=si と同じだ。なお、ls コマンドの場合、 -k オプションはファイルの見かけのサイズの表示に影響しないのに対し、 --block-size オプションは影響することに注意していただきたい。

浮動小数点数
======

浮動小数点数を受け取ったり、生成したりするコマンドは、下層で動いているシステムの浮動小数点表現法を使用しており、丸めエラー、オーバーフローなど、浮動小数点にかかわる問題をかかえている。最近のシステムでは、ほとんどすべてが IEEE-754 の浮動小数点を採用しているので、今日では IEEE-754 の動作を想定しておけば、たいていどこでも問題がない。 IEEE-754 には、正と負の無限があり、正と負のゼロを区別する。また、NaN (訳注: Not a Number) という特別な値を使って、ゼロをゼロで割るといった無効な演算を表現する。より詳しい情報については、デイビッド・ゴールドバーグの論文 "What Every Computer Scientist Should Know About Floating-Point Arithmetic" (http://www.validlab.com/goldberg/paper.pdf) をご覧になるとよい。

浮動小数点数をオプションやオペランドや入力として受け取るコマンドは、 C の標準関数 strtod や strtold を使って、テキストを浮動小数点数に変換している。従って、そうした浮動小数点数には、 1.0e-34 や -10e100 といった指数表現が使用できる。浮動小数点を解析するコマンドは、大文字小文字を区別しない inf, infinity,NaN といった値も理解する。もっとも、そうした値が役に立つかどうかは、そのコマンド次第だ。最近の C の実装では、16 進の浮動小数点数も使える。たとえば、-0x.ep-3 といったものだが、これは -14/16 掛ける 2^-3 を表し、-0.109375 に等しい。小数点を表す記号が何になるかは、 LC_NUMERIC のロケールによって決まる。 See Parsing of Floats (The GNU C Library Reference Manual).

シグナルの指定
=======

SIGNAL の指定には、HUP のようなシグナル名や 1 のようなシグナル番号、それに、シグナルによって終了させられるときのプロセスの終了ステータスを使うことができる (訳注: 最後のものは、GNU coreutils の kill コマンドでは使用できるが、シェルの組み込みコマンドのような、他の系統の kill では使えないかもしれない)。シグナル名は、標準的な形式でも、頭に SIG を付けた形式でも構わない。大文字小文字は区別されない。以下に挙げるシグナル名とシグナル番号は、POSIX の規格に従っているすべてのシステムで使用できる。

HUP
     1.  ハングアップ (Hangup)。

INT
     2.  端末からの割り込みシグナル (Terminal interrupt)。

QUIT
     3.  端末からの中止シグナル (Terminal quit)。

ABRT
     6. プロセスの中断 (Process abort)。

KILL
     9.  強制終了 (Kill) (捕獲することも無視することもできない)。

ALRM
     14.  アラームクロック (Alarm Clock)。

TERM
     15.  終了 (Termination)。

これ以外にもサポートされているシグナル名があるが、それに対応するシグナル番号はシステムによって様々である。 POSIX 1003.1-2001 に準拠しているすべてのシステムでは、以下のシグナルも使用できる。

BUS
     メモリオブジェクトの未定義領域へのアクセス。

CHLD
     チャイルドプロセスが終了 (terminate)、一時停止 (stop)、または再開 (continue) した。

CONT
     実行が停止 (stop) しているならば、再開 (continue) する。

FPE
     誤った算術演算。

ILL
     不正な命令。

PIPE
     読み手のないパイプへの書き出し。

SEGV
     無効なメモリ参照。

STOP
     実行を一時停止する (stop) (捕獲することも無視することもできない)。

TSTP
     端末からの一時停止シグナル。

TTIN
     バックグラウンドプロセスが端末から読み込もうとしている。

TTOU
     バックグラウンドプロセスが端末へ書き出そうとしている。

URG
     高帯域幅のデータがソケットに達している。

USR1
     ユーザ定義シグナル 1。

USR2
     ユーザ定義シグナル 2。

XSI 拡張に対応している POSIX 1003.1-2001 のシステムでは、以下のシグナルも使用できる。

POLL
     ポーリング可能なイベント。

PROF
     プロファイリング・タイマーがタイムアウトした。

SYS
     不正なシステムコール。

TRAP
     Trace/breakpoint トラップ。

VTALRM
     バーチャル・タイマーがタイムアウトした。

XCPU
     CPU 時間の上限を超過した。

XFSZ
     ファイルサイズの上限を超過した。

XRT 拡張に対応している POSIX 1003.1-2001 のシステムでは、上記以外にも、少なくとも 8 個のリアルタイム・シグナルが使用できる。すなわち、RTMIN, RTMIN+1, ..., RTMAX-1, RTMAX などだ。

chown, chgrp, chroot, id: ユーザ名かユーザ ID かを明確にする
=============================================

chown, chgrp, chroot, id といったコマンドでは、引数として OWNER や GROUP を渡す際に名前で指定しても、ID 番号で指定してもよい。この指定法が曖昧であることは明らかである。もし、ユーザ名やグループ名が数字の連続だったら、どうだろう？ (環境によっては、ユーザ名に数字を使うのは、よくあることである。) コマンドはそれをユーザ名と解釈すべきだろうか？ ID 番号と解釈すべきだろうか？ POSIX では、「こうしたコマンドは、指定された文字列をまず名前として解決することを試み、それに失敗した場合のみ、ID 番号として解釈しようとすること」と規定している。この規定では、ユーザが引数として ID 番号、たとえば 42 を指定しようとすると、面倒な話になる。42 というユーザ名が存在し、それにユーザ ID 番号として別の数字、たとえば 1000 が割り当てられているといったややこしい状況でも、うまく処理できなければならないとすると、厄介なことになるのだ。単に chown 42 F を実行したのでは、ファイル F の所有者の ID 番号が 1000 になってしまう。これはユーザが意図した動作ではない。

GNU の chown, chgrp, chroot,id は、この問題に対する回避策を用意している。この回避策を使用すると、データベースの検索を省略するので、処理速度が著しく向上することがあるというおまけまで付く。ユーザやグループに ID 番号を指定する際には、その前に + を付けさえすればよい。そうすれば、整数として解釈するように強制できるのである。

     chown +42 F
     chgrp +$numeric_group_id another-file
     chown +0:+0 /

+ が前に付く各文字列に対しては、ユーザ名の検索プロセスが省略される。何故なら、+ を含む文字列が有効なユーザ名やグループ名であることは絶対にないからだ。この書き方は、よく使われているたいていの Unix システムで使用できるが、Solaris 10 では使用できない。

ランダムデータのソース
===========

shuf, shred, sort コマンドは、作業を行うためにランダムデータを必要とすることがある。たとえば、sort -R ではハッシュ関数をランダムに選ばねばならず、その選択のためにランダムデータを必要としている。

デフォルトでは、こうしたコマンドは、プログラム内部の擬似乱数ジェネレータを、少量のエントロピーによって初期化して使用するが、 --random-source=FILE オプションで、外部ソースを使うように指示することもできる。 FILE の中身のバイト数が不十分なときは、エラーが通知される。

たとえば、デバイスファイル /dev/urandom を、ランダムデータのソースとして使用してもよい。通常、このデバイスは、デバイスドライバーなどのソースから環境ノイズを集めて、エントロピー・プールに入れ、そのプールを使って、ランダムなビットを生成する。プールにデータが足りない場合は、内部プールを再利用し、暗号的に安全な擬似乱数ジェネレータを使って、より多くのビットを作り出す。とは言え、このデバイスは、大量のランダムデータの生成のために設計されたものではなく、比較的動作が遅いことは、承知しておいた方がよい。

たいていの実用には、/dev/urandom で十分だが、プライベートなデータの高度で長期に渡る保護が必要になるアプリケーションでは、 /dev/random や /dev/arandom のような他のデータソースが必要になるかもしれない。どんなデータソースが利用できるかは、ご使用のオペレーティング・システム次第だ。

前回コマンドを実行したときの結果を再現するには、何らかのランダムデータをファイルに保存しておき、そのコマンドの一回目の実行でも二回目の実行でも、ランダムソースとしてそのファイルを使用すればよい。ファイルを使用する代わりに、たとえば、次のような方法を使っても、ある値を種として与えたときの、再現性のある適当な量の擬似ランダムデータを生成することができる。

     get_seeded_random()
     {
       seed="$1"
       openssl enc -aes-256-ctr -pass pass:"$seed" -nosalt \
         </dev/zero 2>/dev/null
     }

     shuf -i1-100 --random-source=<(get_seeded_random 42)

出力先ディレクトリ
=========

通常、cp, install, ln, mv といったコマンドは、最後のオペランドがディレクトリやディレクトリへのシンボリックリンクの場合、それを特別扱いする。たとえば、cp source dest は、dest がディレクトリならば、cp source dest/source と同じことである。時には、そうした動作が、ユーザが求めている動作とは違うこともある。そこで、こうしたコマンドは、よりきめ細かな制御ができるように、以下のオプションをサポートしている。

-T
--no-target-directory
     最後のオペランドが、ディレクトリやディレクトリへのシンボリックリンクであっても、それを特別扱いしない。このオプションは、複数のプログラムが共有領域で作業するとき、競合状態を防止する一助になる。たとえば、mv /tmp/source /tmp/dest というコマンドが正常終了しても、 /tmp/source が /tmp/dest にリネームされたという保証はない。もし、何かほかのプロセスが /tmp/dest をディレクトリとして作成していたら、 /tmp/dest/source という名前のファイルになってしまうかもしれないのだ。それに対して、mv -T /tmp/source /tmp/dest が正常終了した場合は、 /tmp/source は間違いなく /tmp/dest にリネームされている。

     反対に、最後のオペランドをディレクトリとして扱わせたい、それができない場合は、エラーメッセージを出したい、ということもある。そういうときは、--target-directory (-t) オプションを使用すればよい。 (訳注: ターゲット・ディレクトリをコマンドラインの最後に置く代わりに、 --target-directory オプションの引数にするということである。)

-t DIRECTORY
--target-directory=DIRECTORY
     DIRECTORY を、出力されるファイルすべてのディレクトリ部分として使用する。

     ほとんどのプログラムで、コマンドラインの扱いは次のようになっている。オプションや、一定数の (0 個のこともある) 位置の固定した引数の処理が終われば、引数リストにはもう何も残っていないか、残っているとすれば、それはすべて同じように処理されることになる項目 (通常はファイル) のリストのはずある。 xargs プログラムは、こうした約束ごとに沿ってうまく動くように作られている。

     mv ファミリーのコマンドが変わっているのは、引数の数が不定であり、しかも最後の引数を特別扱いするという点である (すなわちターゲット・ディレクトリとして扱う)。そのため、ある種の作業の実行は、一筋縄ではいかない。たとえば、「すべてのファイルをここから ../d/ に移動する」がそうだ。何故なら、mv * ../d/ では、引数を入れておくための領域を使い切ってしまうかもしれないし、そうかと言って、ls | xargs ... には、実行対象コマンド (訳注: ここでは、mv) を起動するたびに最後の引数を特別に指定するためのすっきりした方法がないからである。 (シェルコマンドを駆使すれば、できないことはないが、それでは、人間の労力と脳力を過当に要求することになる。)

     --target-directory (-t) オプションを使用すると、 cp, mv, ln, install といったプログラムを xargs と一緒に使うとき、たいへん都合がよい。たとえば、カレントディレクトリから、同じディレクトリ階層にある d ディレクトリへファイルを移動するには、こんなふうにすればよい。

          ls | xargs mv -t ../d --

     しかし、これでは、ファイル名の先頭に . の付くファイルが移動しない。GNU find プログラムを使えば、次のコマンドでそうしたファイルも移動させることができる。

          find . -mindepth 1 -maxdepth 1 \
            | xargs mv -t ../d

     とは言え、上記のどちらの方法も、カレントディレクトリにファイルが一つもない場合や、空白などの特殊文字を名前に含むファイルがある場合には、うまく行かない。次の例はそうした制限を一掃しているが、GNU find と GNU xargs の両方が必要である。

          find . -mindepth 1 -maxdepth 1 -print0 \
            | xargs --null --no-run-if-empty \
                mv -t ../d

--target-directory (-t) オプションと --no-target-directory (-T) オプションを一緒に使うことはできない。

末尾のスラッシュ
========

いくつかの GNU プログラム (少なくとも、cp と mv) では、 SOURCE 引数を処理する前に、その引数の末尾にスラッシュが付いていたら、それを除去することができるようになっている。--strip-trailing-slashes オプションを使用することによって、この動作が有効になる。

これが役に立つのは、SOURCE 引数の末尾にスラッシュが付いていて、しかも、その引数がディレクトリへのシンボリックリンクを指定しているかもしれないときだ。そうした状況は、実のところ、それほど珍しくない。と言うのも、シェルの中には、そうしたシンボリックリンクに対してファイル名の補完を行うとき、末尾にスラッシュを自動的に付加するものがあるからだ。このオプションを指定しないと、たとえば mv は、(システムの rename 関数を通してだが、) 末尾にスラッシュが付いていることを、「シンボリックリンクの参照をたどれ」という指示として解釈しなければならず、その結果、シンボリックリンクではなく、間接的に参照されているディレクトリの方をリネームしなければならなくなる。こうした動作がデフォルトになっているのは意外に思えるかもしれないが、POSIX で要求されている動作であり、POSIX 規格のほかの部分とも首尾一貫している。

シンボリックリンクをたどる
=============

以下のオプションは、--recursive (-R) オプションも同時に指定されているとき、chown コマンドや chgrp コマンドがディレクトリ階層をどうたどるか、そのたどり方を変更する。以下のオプションを複数個指定した場合は、最後に指定したものだけが効果を持つ。こうしたオプションが指定しているのは、ディレクトリに対するシンボリックリンクを処理する際に、そのシンボリックリンクそのものを操作の対象にするのか、それとも、そのディレクトリ以下の階層にあるすべてのファイルを操作の対象にするのかということである。

こうしたオプションは、--dereference や --no-dereference (-h)とは、全く別のものである。あちらは、シンボリックリンクを変更するのか、それとも、その参照先を変更するのかを制御している。

-H
     --recursive (-R) オプションが指定されている場合に、コマンドラインで指定された引数がディレクトリへのシンボリックリンクならば、それをたどる。

-L
     ディレクトリ階層を再帰的にたどっている際に、ディレクトリへのシンボリックリンクに出会ったら、必ずそれをたどる。

-P
     シンボリックリンクを一切たどらない。これが、-H, -L, -P のどれも指定されていないときの、デフォルトである。

/ (ルート) を特別扱いする
===============

ある種のコマンドは、ディレクトリ階層全体に対して破壊的な作用を及ぼす可能性がある。たとえば、しかるべき特権を持ったユーザが、rm -rf / tmp/junk を誤って実行したら、システム全体のすべてのファイルが消えてしまうかもしれないのだ。そうしたコマンドの使用が正当であることは、めったにないので、GNU の rm は、/ に還元されるようないかなるディレクトリに対しても、通常では、操作を拒否するようになっている。もし、本当にシステムのすべてのファイルを消去しようと思うのなら、 --no-preserve-root オプションを使用すればよい。とは言え、ほとんどの用途で、デフォルトの動作 (明示的に指定するには、 --preserve-root オプションを使う) の方が安全である。

chgrp, chmod, chown などのコマンドも、ディレクトリ階層全体に対して破壊的な作用を及ぼす可能性がある。従って、こうしたコマンドもまた、上記のオプションをサポートしている。こうしたコマンドは、rm とは違って、ファイルを実際に削除してしまうわけではないが、 / から再帰的に働くときは、一層危険だと言うこともできる。と言うのは、たいていの場合、処理速度がずっと早いので、注意力のあるユーザがコマンドを中断できるより前に、rm の場合より、もっと多くのファイルに被害を与えてしまうからだ。Unix の習慣も POSIX の規格も、こうしたコマンドが / から再帰的に働くことを要求している。それ故、デフォルトが --no-preserve-root になっているのだが、こうしたコマンドは、--preserve-root オプションを使った方が、ほとんどの用途でより安全である。面倒ならば、エイリアスか、シェル関数を作って、--preserve-root を指定しておけばよいのだ。

また、--preserve-root を指定すると、/ を指しているシンボリックリンクの参照をたどる場合でも、chgrp や chown が、/ のグループや所有者を変更しなくなることも、憶えておいていただきたい。 (訳注: chgrp や chown の解説を見ていただけばわかるが、これは、--recursive (-R) を同時に使っているときの話である。)

特殊ビルトイン・ユーティリティ
===============

プログラムの中には、nice のように、ほかのプログラムを起動できるものがある。たとえば、nice cat file というコマンドは、コマンド cat file を実行することによって、cat プログラムを起動する。しかしながら、exit のようなシェルの特殊ビルトイン・ユーティリティ (special built-in utilities) は、この方法で起動することができない。一例を挙げれば、nice exit というコマンドは、どんな動作をするかが明確に定義されていない。終了する代わりに、エラーメッセージを出すかもしれないのだ。

POSIX 1003.1-2004 の規格では、特殊ビルトイン・ユーティリティとして次のものを挙げている。

     . : break continue eval exec exit export readonly return set shift times trap unset

たとえば、., :, exec は、特殊ビルトイン・ユーティリティなので、 nice . foo.sh, nice :, nice exec pwd といったコマンドの動作は、読者が予想なさるかもしれないようなものにはならない。

(訳注: exec, exit など対して、同じシェルの組み込みコマンドでも、cd, alias, fg, kill, pwd, true, umask などは、通常ビルトイン・ユーティリティ ("regular built-in utilities") と呼ばれている。もっとも、nice などから実行できないという点では、特殊ビルトイン・ユーティリティも通常ビルトイン・ユーティリティも変わりがない。 nice などから起動できるとすれば、それは同名の実行ファイルが存在するからだ)。

多くのシェルは、上記のリストを拡張している。たとえば、bash では、history や suspend といったコマンドが特殊ビルトイン・ユーティリティに追加されている。そこで、bash の場合、nice suspend というコマンドを実行すると、シェルのサスペンドは起こらず、エラーメッセージが出力される。

規格への準拠
======

GNU ユーティリティのデフォルトの動作が POSIX の規格と一致しない場合が、若干ながら存在する。そうした非互換性を抑制するには、環境変数 POSIXLY_CORRECT を設定すればよい。もっとも、POSIX に準拠しているか否かを点検しているのでもないかぎり、 POSIXLY_CORRECT を設定する必要は、おそらくないだろうが。

POSIX の新しいバージョンが、古いバージョンと非互換であることが、ときどきある。たとえば、POSIX の古いバージョンでは、sort +1 というコマンドは、各入力行の二番目以後のフィールドに基づいて、行の並べ替えを行うことになっていた。ところが、POSIX 1003.1-2001 では、同じコマンドが +1 という名前のファイルの行を並べ替えることになっており、フィールドに基づいた並べ替えを行うには、sort -k 2 という別のコマンドを使わなければならないのだ。そして、さらにややこしいことに、POSIX 1003.1-2008 では、古い動作と新しい動作のどちらをする実装も認められている。

通常 GNU のユーティリティは、お使いのシステムが規格として採用している POSIX のバージョンに従っている。GNU ユーティリティを POSIX の別のバージョンに準拠させるには、環境変数 _POSIX2_VERSION を設定すればよい。この環境変数の値は、YYYYMM という形式であり、その規格が何年の何月に採択されたかを示している。_POSIX2_VERSION の値としては、現在のところ、次の三つがサポートされている。すなわち、199209, 200112, 200809 であり、それぞれ POSIX 1003.2-1992, POSIX 1003.1-2001, POSIX 1003.1-2008 を表している。一例を挙げよう。御使用のシステムが POSIX 1003.1-2001 に準拠しているのに、動かしているソフトウェアが sort +1 や tail +10 といった旧来の用法も持っている場合には、環境に _POSIX2_VERSION=200809 を設定することで、互換性の問題を回避することができる。

coreutils: Multi-call プログラム
===========================

coreutils コマンドは個々のユーティリティ・プログラムを呼び出す。呼び出されるユーティリティ・プログラムは、coreutils を呼び出すために使ったファイル名の最後の要素によって自動的に選ばれたものか、あるいは、--coreutils-prog オプションを使って明示的に指定されたものである。

書式:

     coreutils --coreutils-prog=PROGRAM ...

coreutils は、デフォルトではインストールされない。従って、移植を考慮したスクリプトでは、その存在を当てにしない方がよい。

(訳注: 少し説明が必要だろう。coreutils 8.23 以来、ls, sort など、個々のバイナリを作るのではなく、coreutils という一つの大きなバイナリを作り、 ls, sort などは、言わば coreutils のビルトイン・コマンドとして呼び出すことができるようになった。つまり、ls は今までどおり ls や /bin/ls でも起動できれば、 coreutils --coreutils-prog=ls でも起動できるということである。前者の場合のベースネームの ls が、本文で言う「coreutils を呼び出すために使ったファイル名の最後の要素」に当たるわけだ。もちろん、今でも個々のコマンドを独立したバイナリとして作ることもでき、その場合は、たぶん coreutils というコマンドは存在しないことになる。詳しくは、coreutils パッケージに含まれる NEWS ファイルをご覧いただきたい。)

ファイル全体の出力
*********

次のコマンドはファイル全体を読み込んで、書き出す。内容に対して何らかの変換を行うこともある。

cat: ファイルを結合して、書き出す
===================

cat は、各 FILE (- は標準入力を意味する) を標準出力にコピーする。 FILE が一つも指定されていない場合は、標準入力から読み込む。

書式:

     cat [OPTION] [FILE]...

このプログラムでは以下のオプションが使用できる。参照: Common options.

-A
--show-all
     -vET と同じ。

-b
--number-nonblank
     空行以外のすべての出力行に、1 から始まる番号を付ける。

-e
     -vE と同じ。

-E
--show-ends
     各行の末尾に $ 記号を付ける。

-n
--number
     すべての出力行に、1 から始まる番号を付ける。このオプションは、-b が有効になっているときは、無視される。

-s
--squeeze-blank
     連続する空行の表示を抑制する。すなわち、連続する複数の空行の代わりに、たった 1 行だけ空行を出力する。

-t
     -vT と同じ。

-T
--show-tabs
     TAB 文字を ^I と表示する。

-u
     無視される。POSIX との互換のためにある。

-v
--show-nonprinting
     LFD と TAB 以外の制御文字を ^ 表記を使って表示する。高位ビットのセットされている文字の前には、M- を付ける。

テキストファイルとバイナリファイルを区別する MS-DOS のようなシステムでは、 cat は通常、バイナリモードで読み書きを行う。しかしながら、-bensAE といったオプションの一つが使われている場合や、読み込みの対象が標準入力で、しかも、標準入力が端末である場合は、cat はテキストモードで読み込みを行う。同様に出力においても、-bensAE といったオプションの一つが使用されていたり、標準出力が端末である場合は、 cat はテキストモードで書き出しを行う。

終了ステータス 0 は成功を示し、0 以外の値は失敗を示す。

用例:

     # f の内容、標準入力、g の内容の順で出力する。
     cat f - g

     # 標準入力を標準出力にコピーする。
     cat

tac: ファイルを結合し、ファイルごとに逆順で書き出す
============================

tac は、各 FILE (- は標準入力を意味する) を、FILE ごとにレコード (records、デフォルトでは行) の順番を逆にして、標準出力にコピーする。 FILE が一つも指定されていない場合は、標準入力から読み込む。

書式:

     tac [OPTION]... [FILE]...

レコード (records) は、ある文字列 (デフォルトでは改行) が出現することによって区切られる。出力の際、デフォルトでは、この区切り文字列は、ファイル中でその区切り文字列の直前にあるレコードの末尾に付加される。

このプログラムでは以下のオプションが使用できる。参照: Common options.

-b
--before
     出力の際、区切り文字列は、ファイル中でその区切り文字列の直後に来るレコードの先頭に付加される。

-r
--regex
     区切り文字列を正規表現として処理する。

-s SEPARATOR
--separator=SEPARATOR
     改行の代わりに SEPARATOR をレコード区切り文字列 (record separator) として使用する。注意すべきは、SEPARATOR に空文字列を指定すると、ゼロバイトを指定したことになることだ。すなわち、入出力レコードが ASCII NUL で区切られることになる。

テキストファイルとバイナリファイルを区別する MS-DOS のようなシステムでは、 tac はバイナリモードで読み書きを行う。

終了ステータス 0 は成功を示し、0 以外の値は失敗を示す。

用例:

     # ファイルを一字一字逆にする。
     tac -r -s 'x\|[^x]'

nl: 行番号を付けて、ファイルを書き出す
=====================

nl は、各 FILE (- は標準入力を意味する) を、すべての行、または、一部の行に行番号を付けて、標準出力に書き出す。 FILE が一つも指定されていない場合は、標準入力から読み込む。

書式:

     nl [OPTION]... [FILE]...

nl は、入力を (論理) ページセクションに分解する。デフォルトでは、行番号は各論理ページセクションで 1 にリセットされる。 nl は、すべての入力ファイルをまとめて、一つのドキュメントとして扱う。従って、入力ファイルが変わるたびに、論理ページや行番号をリセットすることはない。

論理ページは、三つのセクションからなる。すなわち、ヘッダ、本文、フッタである。どのセクションも空であって構わない。セクションごとに他のセクションとは異なる番号付けの方式を選ぶこともできる。

入力ファイル中で論理ページの各セクションが始まる位置を指示するには、以下の区切り文字列の一つのみからなる行を使用する。

\:\:\:
     ヘッダの先頭。

\:\:
     本文の先頭。

\:
     フッタの先頭。

上記の文字列を構成する二文字は、オプションを使って (下記参照)、\ と : の組み合わせ以外のものに、変更することができる。だが、各文字列のパターンや長さは、変えることができない。

セクションの区切りは、出力では空行に置き換えられる。入力ファイル中の最初のセクション区切り文字列より前にあるテキストは、いかなるテキストも、本文セクションの一部と見なされる。従って、nl は、セクションの区切りを全く含まないファイルを、一個の本文セクションとして扱う。

このプログラムでは以下のオプションが使用できる。参照: Common options.

-b STYLE
--body-numbering=STYLE
     各論理ページの本文セクションにおける行の番号付けの方式を選択する。行に番号が付かない場合、行番号の現在値は増加しないが、それでも行番号の区切り文字は行の前に付く (訳注: ここで言う行番号の区切り文字 (line number separator character) とは、行番号とテキストの区切り文字ではなく、行頭とテキストとの間にある行番号のために用意された空間を埋める空白のことらしい)。番号付けの方式には、以下のものがある。

     a
          すべての行に番号を振る。

     t
          空ではない行にのみ番号を振る (本文のデフォルト)。

     n
          行番号を付けない (ヘッダとフッタのデフォルト)。

     pBRE
          基本正規表現 BRE にマッチする部分を含む行にのみ番号を振る。 See Regular Expressions (The GNU Grep Manual).

-d CD
--section-delimiter=CD
     セクションの区切り文字を CD にする。デフォルトは \:。 C のみを指定すると、二番目の文字は、デフォルトと同じ : になる。 (\ などのメタ文字は、シェルが展開しないように、引用符やバックスラッシュで保護するのをお忘れなく。)

-f STYLE
--footer-numbering=STYLE
     --body-numbering と同様。

-h STYLE
--header-numbering=STYLE
     --body-numbering と同様。

-i NUMBER
--line-increment=NUMBER
     行番号を NUMBER づつ増やす (デフォルトは 1)。

-l NUMBER
--join-blank-lines=NUMBER
     空行にも番号を付けるとき、連続する NUMBER (デフォルトは 1) 行の空行を 1 論理行と数え、最後の空行にのみ番号を振る。連続する空行が NUMBER 行未満のときは、番号を振らない。空行というのは、文字を全く含まない、スペースやタブさえも含まない行のことである。

-n FORMAT
--number-format=FORMAT
     行番号付けのフォーマットを選択する (デフォルトは rn)。

     ln
          左詰めにする。先頭を 0 で埋めない。

     rn
          右詰めにする。先頭を 0 で埋めない。

     rz
          右詰めにする。先頭を 0 で埋める。

-p
--no-renumber
     論理ページの先頭で行番号をリセットしない。

-s STRING
--number-separator=STRING
     出力中で行番号とテキスト部分との区切りに STRING を使う (デフォルトはタブ文字)。

-v NUMBER
--starting-line-number=NUMBER
     各論理ページで行番号を NUMBER から始める (デフォルトは 1)。

-w NUMBER
--number-width=NUMBER
     行番号に  NUMBER 個の文字を使用する (デフォルトは 6 文字)。

終了ステータス 0 は成功を示し、0 以外の値は失敗を示す。

od: ファイルを 8 進数などの形式で書き出す
========================

od は、各 FILE (- は標準入力を意味する) の内容を、曖昧さの余地がない形で標準出力に書き出す。FILE が一つも指定されていない場合は、標準入力から読み込む。

書式:

     od [OPTION]... [FILE]...
     od [-abcdfilosx]... [FILE] [[+]OFFSET[.][b]]
     od [OPTION]... --traditional [FILE]
      [[+]OFFSET[.][b] [[+]LABEL[.][b]]]

各出力行の構成は、入力中の位置をオフセットで表したものの後に、ファイルのデータをいくつかのまとまりに分けたものが続くという形になっている。デフォルトでは、od はオフセットを 8 進数で表示する。ファイル・データの個々のまとまりは、入力を C 言語の short int ごとに分けたものであり、1 個の 8 進数として表示される。

OFFSET を指定した場合、それは、整形と出力を始める前に、入力を何バイト読み飛ばすかを示している。デフォルトでは、OFFSET は 8 進数と見なされるが、数字の後ろに小数点を付ければ、10 進数と見なされる。小数点が指定されず、オフセットの数字が 0x や 0X で始まっている場合は、 16 進数として解釈される。もし、数字の後ろに b が付いているならば、読み飛ばすバイト数は、OFFSET に 512 を掛けたものになる。

(訳注: 数字の後ろに小数点を付けることで OFFSET が 10 進数であることを示す方法は、現在では無効のようである。オフセットを 10 進数で指定したければ、-j オプションを使用した方がよい。)

コマンドが「書式」における第一の型と第二の型のどちらとも取れるときは、最後のオペランドが + で始まっている場合や、オペランドが 2 個で 2 番目のオペランドが数字で始まっている場合は、第二の型だと見なされる。たとえば、od foo 10 や od +10 では、10 はオフセットである。それに対して、od 10 では、10 はファイル名である。

このプログラムでは以下のオプションが使用できる。参照: Common options.

-A RADIX
--address-radix=RADIX
     ファイル・オフセットの表示に使う基数を選択する。RADIX には、以下の一つが使える。

     d
          10 進数

     o
          8 進数

     x
          16 進数

     n
          なし (オフセットを表示しない)

     デフォルトは 8 進数である。

--endian=ORDER
     入力のバイトオーダーを変更する。入力を別のバイトオーダーで扱うため、あるいは、使用システムのエンディアン方式にとらわれない一貫した出力を生成するために使用する。変換は、--type で指定されたサイズと ORDER のエンディアンに従って行われる。 ORDER には、little または big が指定できる。

-j BYTES
--skip-bytes=BYTES
     整形と出力を行う前に、入力を BYTES バイト読み飛ばす。BYTES が 0x や 0X で始まっている場合は、16 進数と見なされる。 0 のみで始まっている場合は、8 進数だ。どちらでもない場合は、10 進数である。 BYTES は、整数であり、以下に挙げるような何倍かを示す接尾辞を後ろに付けることもできる。接尾辞だけ指定してもよい (訳注: その場合は、1 が前にあるものと見なされる)。

          b  =>            512 ("blocks")
          KB =>           1000 (KiloBytes)
          K  =>           1024 (KibiBytes)
          MB =>      1000*1000 (MegaBytes)
          M  =>      1024*1024 (MebiBytes)
          GB => 1000*1000*1000 (GigaBytes)
          G  => 1024*1024*1024 (GibiBytes)

     T, P, E, Z, Y についても同様。

-N BYTES
--read-bytes=BYTES
     入力から最大で BYTES バイト出力する。bytes に接頭辞や接尾辞を付けると、 -j オプションの場合と同じように解釈される。

-S BYTES
--strings[=BYTES]
     通常の出力はせず、文字列定数 (string constants) のみを出力する。すなわち、BYTES バイト以上の連続する ASCII 表示文字で、ゼロバイト (ASCII NUL) が続くものを出力するわけだ。BYTES に接頭辞や接尾辞を付けると、 -j オプションの場合と同じように解釈される。

     --strings に続く BYTES が省略された場合、デフォルトは 3 である。 (訳注: 短縮形の -S では BYTES を省略できない。)

-t TYPE
--format=TYPE
     ファイルデータの出力形式を選択する。 TYPE は、1 個以上の下記の形式指定文字からなる文字列である。一つの TYPE 文字列に複数の形式指定文字が含まれている場合や、このオプションを複数回使用した場合は、od は出力行ごとに、指定された各データ形式で表現したその行を、指定された順番で書き出す。

     どんな形式指定であれ、その最後に ``z'' を付けると、形式指定によって生成された出力行の後ろに、表示可能文字を 1 バイト文字によって表現したものが、出力される。

     a
          文字の名称 (訳注: たとえば、A は A、改行文字は nl)。最上位ビットは無視する。

     c
          表示可能な 1 バイト文字、C 言語のバックスラッシュ・エスケープ、あるいは 3 桁の 8 進数。

     d
          符号付き 10 進数

     f
          浮動小数点数 (see Floating point)

     o
          8 進数

     u
          符号なし 10 進数

     x
          16 進数

     a 形式の出力では、空白文字は sp、改行文字は nl、ゼロバイトは nul といった具合に表現される。このとき、各バイトの下位 7 ビットのみが使われ、最上位ビットは無視される。c 形式の出力では、上記の例は、それぞれ、\n、\0 になる。

     a と c 形式を除き、形式指定文字の後ろに 10 進数の整数を続けることによって、入力データの各数値を読み込んで、指定されたデータ形式に変換して行く際に、何バイトづつ使用するかを指定することができる。あるいは、形式指定文字の後ろに以下の文字の一つを続けることによって、 C コンパイラの組み込みデータ型のいづれかのサイズを指定することも可能だ。すなわち、整数 (d, o, u, x) に対しては、以下を後置する。

     C
          char

     S
          short

     I
          int

     L
          long

     浮動小数点数 (f) に対しては、次のものが使用できる。

     F
          float

     D
          double

     L
          long double

-v
--output-duplicates
     連続する行が同一であっても出力する。デフォルトでは、出力する行が、二行以上連続して全く同一になりそうな場合、od は最初の行だけを出力し、次の行にはアステリスクのみを置いて、二行目以下を省略したことを示す。

-w[N]
--width[=N]
     1 出力行当たり、n バイトの入力をダンプする。この値は、指定した各出力形式に結び付いているサイズの最小公倍数の倍数でなければならない。

     このオプションが全く指定されないときのデフォルトは 16 である。このオプションが N なしで指定されたときのデフォルトは 32 である。

以下に挙げるいくつかのオプションは、形式指定の簡易版である。GNU od では、形式指定オプションと簡易版オプションをどのように組み合わせても構わない。こうしたオプションは、累加されていく。

-a
     文字の名称で出力する。-t a と同じ。

-b
     1 バイトづつ 8 進数として出力する。-t o1 と同じ。

-c
     表示可能な 1 バイト文字か、C 言語のバックスラッシュ・エスケープ、あるいは 3 桁の 8 進数として出力する。-t c と同じ。

-d
     2 バイトづつ符号なし 10 進数として出力する。-t u2 と同じ。

-f
     浮動小数点数として出力する。-t fF と同じ。

-i
     10 進数の int として出力する。-t dI と同じ。

-l
     10 進数の long int として出力する。-t dL と同じ。

-o
     2 バイトづつ 8 進数として出力する。-t o2 と同じ。

-s
     2 バイトづつ 10 進数として出力する。-t d2 と同じ。

-x
     2 バイトづつ 16 進数として出力する。-t x2 と同じ。

--traditional
     昔の od で使用できた、オプションではない引数 LABEL を認識する。書式は次のようになる。

          od --traditional [FILE] [[+]OFFSET[.][b] [[+]LABEL[.][b]]]

     この書式を使用すると、ファイルは 1 個までしか指定できないが、必要なら、オフセットを示す引数や、LABEL という、開始位置の仮アドレスを示す引数を、続けて指定することができる。引数 LABEL は OFFSET と全く同じように解釈されるが、出力を開始する位置の仮アドレスを指定している。仮アドレスは、通常のアドレスの後ろに、カッコで囲まれて、表示される。

終了ステータス 0 は成功を示し、0 以外の値は失敗を示す。

base32: データを表示可能データ (printable data) に変換する
==========================================

base32 はファイル、または標準入力から読み込んだデータを、 base32 でエンコードした形式に変換する (あるいは、その逆を行う)。 base32 でエンコードした形式は、表示可能な ASCII 文字を用いて、バイナリデータを表現する。このコマンドの使用法やオプションは、 base64 と全く同じである。  See base64 invocation.

base64: データを表示可能データ (printable data) に変換する
==========================================

base64 はファイル、または標準入力から読み込んだデータを、 base64 でエンコードした形式に変換する (あるいは、その逆を行う)。 base64 でエンコードした形式は、表示可能な ASCII 文字を用いて、バイナリデータを表現する。

書式:

     base64 [OPTION]... [FILE]
     base64 --decode [OPTION]... [FILE]

base64 でエンコードすると、データが元のデータのほぼ 133% に増大する。 base32 エンコーディングの場合は、元のデータのほぼ 160% になる。こうしたエンコード形式は、RFC4648 に準拠している。 ftp://ftp.rfc-editor.org/in-notes/rfc4648.txt

このプログラムでは以下のオプションが使用できる。参照: Common options.

-w COLS
--wrap=COLS
     エンコード中に、出力が COLS 文字に達したら改行する。この値は、正の整数でなければならない。

     デフォルトでは、76 文字で改行する。改行を全く行わないようにするには、値を 0 にする。

-d
--decode
     動作モードを変更する。デフォルトの、データをエンコードするモードではなく、データをデコードするモードになる。入力には、base64 でエンコードしたデータが期待され、出力は、エンコードする前のデータになる。

-i
--ignore-garbage
     デコードする際、改行文字がどこに現れても、適切に処理する。デコード中に ASCII 表示可能文字以外を表すバイトが現れたら、一部壊れたデータでもデコードできるように、それを無視する。

終了ステータス 0 は成功を示し、0 以外の値は失敗を示す。

ファイル内容の整形
*********

以下のコマンドは、ファイルの内容を整形し直す。

fmt: パラグラフに分かれたテキストを整形し直す
=========================

fmt は行を折り返したり、結合したりして、出力する各行が指定された文字数に納まるように調整する。 1 行のデフォルトはアスキー文字で 75 文字である。 (訳注: 日本語のテキストは、通常単語を空白で区切らないので、うまく整形できない。)

書式:

     fmt [OPTION]... [FILE]...

fmt は、指定された引数 FILE から (指定されていない場合は、標準入力から) テキストを読み込んで、標準出力に書き出す。

デフォルトでは、空行、単語間の空白、インデント (字下げ) は、出力でもそのまま維持される。インデントの違う入力行が連続する場合は、行の結合は行われない。タブは入力のときにスペースに展開され、出力でタブに戻される。

fmt は、できるだけ文の終わりで改行しようとする。また、文の最初の単語の直後や、文の最後の単語の直前で改行するのは避けようとする。「文の終わり (sentence break)」の定義は、パラグラフがそこで終わっているか、あるいは、単語の末尾に .?! のどれかが付き、さらにスペースが 2 個続くか、行末が来ることである。後者の場合、ピリオドなどとスペース 2 個、あるいは行末の間にカッコや引用符が入っていてもよい。 TeX と同様、fmt は、どこで行を折り返すかを決める前に、パラグラフ全体を読み込む。使用しているアルゴリズムは、Donald E. Knuth と Michael F. Plass が ``Breaking Paragraphs Into Lines'' で提示しているものに変更を加えたものである (`Software---Practice & Experience 誌'、第 11 巻 第 11 号 (November 1981) 1119-1184 ページ)。

このプログラムでは以下のオプションが使用できる。参照: Common options.

-c
--crown-margin
     クラウンマージン・モード (Crown margin mode)。パラグラフ中の最初の 2 行のインデントはそのまま維持し、(同一パラグラフの) それに続く各行の左の余白は 2 行目の左の余白に揃える。

     (訳注: これは要するに、1 行目の行頭を字下げしたお馴染みのスタイルのパラグラフ表示である。逆に 1 行目が左に張り出しているスタイルもありえる。なお、2 行目以降のインデントは、 --crown-margin オプションによって揃えられるわけではなく、入力テキストにおいてすでに揃っていなければならない。さもないと、そもそも同一パラグラフの行と見なされない。)

-t
--tagged-paragraph
     標識 (タグ) 付きパラグラフ・モード (Tagged paragraph mode)。クラウンマージン・モードに似ているが、次の点が違う。パラグラフの最初の行と 2 番目の行のインデントが同じ場合、最初の行は 1 行からなるパラグラフとして扱われる。

-s
--split-only
     行の分割のみを行う。短い行を結合して、長い行を作ることはしない。その結果、サンプル・コードの行のような、すでに整形されたテキストをむやみに結合しないで済む。

-u
--uniform-spacing
     空白の数を一定にする。すなわち、単語間の空白は 1 個に、文の間の空白は 2 個にする。

-WIDTH
-w WIDTH
--width=WIDTH
     出力する各行を、長くても WIDTH 文字までにする (デフォルトは 75 文字。GOAL が指定されている場合は、GOAL プラス 10 文字)。

-g GOAL
--goal=GOAL
     とりあえず、各行を GOAL 文字の長さにしてみようとする。これは、デフォルトでは WIDTH より 7% 短い。

-p PREFIX
--prefix=PREFIX
     PREFIX で始まる行のみを整形の対象にする (PREFIX の前にホワイトスペースがあってもよい)。PREFIX とそれに先行するホワイトスペースは、整形の際に取り除かれ、整形後に各出力行に付け直される。このオプションの用途を一つ挙げると、プログラムのコメントのような行だけを整形し、コードには手を加えないことが考えられる。

終了ステータス 0 は成功を示し、0 以外の値は失敗を示す。

pr: ページ付けや段組みをしてファイルを表示する
=========================

pr は、各 FILE (- は標準入力を表す) を標準出力に書き出す。FILE が指定されていない場合は、標準入力を対象にする。その際、ページ付けを行い、指定があれば段組みをして出力する。また、すべての FILE を一つに統合し、1 段 1 ファイルの形式で平行して表示することもできる。

(訳注: pr はページ構成をするコマンドであって、長い行の折り返しなどの整形をするわけではない。そうしたことは、fmt や fold の仕事である。なお、pr の日本語対応は十分ではない。とくに段組みがうまくいかない。)

書式:

     pr [OPTION]... [FILE]...

デフォルトでは、5 行のヘッダが各ページに付く。2 行の空行、日付・ファイル名・ページ番号からなる 1 行、そしてもう 2 行の空行という形式である。 5 行の空行からなるフッタも出力される。デフォルトのページ長 (PAGE_LENGTH) は 66 行なので、本文に使用されるデフォルトの行数は、56 行になる。ヘッダのテキスト行は、DATE STRING PAGE の形を取り、 STRING の両側に空白を入れて、行の幅がページ幅 (PAGE_WIDTH) いっぱいになるようにしている。DATE は日付であり (詳細については、 --date-format (-D) オプションを参照)、 STRING は中央揃えのヘッダ文字列 (訳注: デフォルトではファイル名)、 PAGE はページ番号である。PAGE という単語の綴りは、 LC_MESSAGES ロケール・カテゴリによって変わってくる。デフォルトの C ロケールでは、Page NUMBER であり、NUMBER の位置には 10 進数のページ番号が入る。

入力にフォームフィード (Form feed) があると、出力では改ページが行われる。フォームフィードが続くと、白紙のページが生ずる。

段組みをした場合、どの段の幅も同じになり、段と段の間には任意の文字列 (デフォルトはスペース) が置かれる。多段組みの出力では、-J オプションを使用しないかぎり、各行は常に PAGE_WIDTH (デフォルトは 72) 文字までに切り詰められる (訳注: これは、各段や段間の空白などを合計した 1 行の長さが、最長でも PAGE_WIDTH 文字までになるということであって、各段がそれぞれ PAGE_WIDTH 文字になるということではない)。 1 段のみの出力では、デフォルトでは行の切り詰めは行われない。その場合でも、行の切り詰めを行うには、-W を使用する。

このプログラムでは以下のオプションが使用できる。参照: Common options.

+FIRST_PAGE[:LAST_PAGE]
--pages=FIRST_PAGE[:LAST_PAGE]
     表示を FIRST_PAGE ページから始めて、 LAST_PAGE ページで終了する。 :LAST_PAGE の指定を省略するのは、ファイルの最後までということである。スキップするページ数を計算する際、入力ファイル中にフォームフィードがあると、そのたびに 1 ページ進むことになる。ページ番号は、+FIRST_PAGE を指定してもしなくても同じになる。デフォルトでは、入力ファイルの最初のページからページ数を数えるからだ (表示される最初のページからではない)。行番号については -N オプションで変更することができる。

-COLUMN
--columns=COLUMN
     個々の FILE に対して COLUMN 段に段組みした出力を生成する (デフォルトは 1 段)。-a オプションを使用しない場合、ページ内で本文は、段内を上から下へと進む。段が増えると、段の幅は自動的に狭くなる。ただし、-W/-w を同時に使用して、PAGE_WIDTH を増加させている場合は、そのかぎりではない。このオプションを使うと、切り詰められる行がたぶん生じるだろう。ページごとの各段の行数は、できるだけ揃えられる。多段組みの本文出力では、オプション -e と -i が有効になる。-J オプションと一緒に使った場合は、段の整列と行の切り詰めは行われない。各行は、元の長さのまま、不定長フィールドとして (free field format) 結合されるのである。その際も、-S オプションによってフィールド・セパレータを指定することは可能だ。なお -COLUMN は、-m オプションと一緒に使用できない。

-a
--across
     個々の FILE を段組みで表示するとき、本文の各行が、段内を上から下へではなく、左の段から右の段へと進むようにする。-COLUMN オプションに指定する段の数は、2 以上でなければならない。行が段の幅に納まらないほど長い場合、その行は切り詰められる。

-c
--show-control-chars
     制御文字をハット表記 (たとえば、^G) を使って表示する。他の非表示文字は、バックスラッシュ付きの 8 進数表記になる。pr のデフォルトでは、非表示文字の表示文字化は行われない。

-d
--double-space
     ダブルスペースで出力する (訳注: すなわち、行間を 1 行分あける)。

-D FORMAT
--date-format=FORMAT
     ヘッダの日付を FORMAT を用いて整形する。FORMAT には、コマンド date +FORMAT で使うのと同じ指定法が使用できる。See date invocation. % で始まる日時の指定を除いて、FORMAT 中の文字はそのまま表示される。従って、このオプションを使用すれば、ヘッダの日付の位置に任意の文字列を指定することもできるわけだ。たとえば、--date-format="Monday morning" といった具合に。

     デフォルトの日付書式は %Y-%m-%d %H:%M という形である (たとえば、 2001-12-04 23:59)。だが、環境変数 POSIXLY_CORRECT が設定され、しかも LC_TIME ロケール・カテゴリが POSIX ロケールを指定している場合は、デフォルトの書式は %b %e %H:%M %Y になる (たとえば、Dec  4 23:59 2001)。

     タイムスタンプは、タイムゾーンのルールに従って表示されるが、そのルールを指定しているのは、環境変数 TZ である。 TZ が設定されていない場合は、システムのデフォルトのルールに従って表示される。 See Specifying the Time Zone with TZ (The GNU C Library Reference Manual).

-e[IN-TABCHAR[IN-TABWIDTH]]
--expand-tabs[=IN-TABCHAR[IN-TABWIDTH]]
     入力の際にタブをスペースに展開する。省略できる引数 IN-TABCHAR は、入力で使われるタブ文字である (デフォルトは TAB 文字)。これも省略できる二番目の引数 IN-TABWIDTH は、入力で使われるタブ文字の幅である。(デフォルトは 8 桁)。

-f
-F
--form-feed
     複数個の改行文字ではなく、1 個のフォームフィードを使用して、出力する各ページを分離する。このオプションによって、 66 行というデフォルトのページの長さが変わることはない。

-h HEADER
--header=HEADER
     ヘッダのファイル名の部分を、中央揃えの HEADER という文字列で置き換える。シェル上では、HEADER はクォートするべきである。また、-h との間に空白を入れた方がよい。

-i[OUT-TABCHAR[OUT-TABWIDTH]]
--output-tabs[=OUT-TABCHAR[OUT-TABWIDTH]]
     出力の際にスペースをタブで置き換える。省略できる引数 OUT-TABCHAR は、出力で使われるタブ文字である (デフォルトは TAB 文字)。これも省略できる二番目の引数 OUT-TABWIDTH は、出力で使われるタブ文字の幅である (デフォルトは 8 桁)。

-J
--join-lines
     長い行は長いまま結合する。段組みオプション -COLUMN, -a -COLUMN, -m と併せて使用する。-W/-w による行の切り詰めが無効になる。段の整列も行わなくなる。--sep-string[=STRING] と併せて使ってもよい。 -J というオプションが (-W や --sep-string とともに) 新たに設けられたのは、-w や -s という、前からある (POSIX に準拠した) オプションを 3 種の段組みオプションと組み合わせて使ったときの混乱を解消するためである。

-l PAGE_LENGTH
--length=PAGE_LENGTH
     1 ページの行数を、ヘッダ行 (及び フッタ行) を含めて、PAGE_LENGTH 行にする (デフォルトは 66 行)。PAGE_LENGTH が 10 行以下だったら、 -t オプションが指定されたかのように、 ヘッダとフッタは省略する。

-m
--merge
     すべての FILE を統合し、各段に 1 ファイルを割り当てて、平行表示する。長すぎて段に納まらない行があれば、-J オプションが使用されていないかぎり、切り詰めが行われる。--sep-string[=STRING] を指定してもよい。いづれかの FILE に (フォームフィードの指定により) 空白のページが存在すると、空白の段が生ずるが、それでも段を分離する記号の STRING は表示される。すなわち、統合されたファイルの最初から最後まで、行番号と (訳注: これはもちろん、-n オプションが指定されている場合) 段の分離記号は、連続して表示されるわけだ。ただし、統合されたページのどの段も空白の場合は、分離記号も行番号も表示されない。デフォルトのヘッダは、DATE PAGE という形式になり、中央には長い空白が挿入される。-h や --header オプションを -m と一緒に使えば、この中央の空白部分に文字列を入れることができる。

-n[NUMBER-SEPARATOR[DIGITS]]
--number-lines[=NUMBER-SEPARATOR[DIGITS]]
     DIGITS の幅の行番号を表示する (DIGITS のデフォルトは 5 桁)。通常の多段組みの出力では、行番号は、各段ごとに本文の最初の DIGITS 桁分の位置を占めるが、-m の出力の場合は、各行の先頭だけに表示される。 1 段組みでは、-m の場合と同様、各行の先頭に付く。デフォルトでは、行数は、入力ファイルの最初の行から数え始める (表示される最初の行からではない。--page や -N オプションを参照)。省略可能な引数 NUMBER-SEPARATOR は、行番号の後ろに付けて、後に続く本文と区別するための文字であり、デフォルトのセパレータはタブ文字である。厳密に言うと、常にタブが表示されるのは、1 段組みの出力のときだけである。タブの幅は、本来タブの現れる位置によって変化し、たとえば、-o オプションで指定される左の余白 (MARGIN) によって変わってくるものである。しかし、多段組みの出力では、「出力される段の幅が同じになる」ことが優先されるため (POSIX の仕様)、タブの幅は、最初の段における値に固定され、左の余白の値が変わっても、変化することはない。従って、NUMBER-SEPARATOR であるタブの位置には、常に一定数のスペースが表示されることになる。スペースをタブに置き換えるかどうかは、出力される位置次第である。

-N LINE_NUMBER
--first-line-number=LINE_NUMBER
     表示される最初のページの最初の行を LINE_NUMBER として行を数えて行く (入力ファイルの最初の行以外から表示を始めるときによく使う)。

-o MARGIN
--indent=MARGIN
     スペース MARGIN 個分の余白で各行をインデントする (デフォルトは、スペース 0 個)。ページの横幅は、-W/-w で指定した PAGE_WIDTH と余白を合計したサイズになる。行番号付きの 1 段組み出力では、行から少しはみ出す文字が生ずるかもしれない (-n オプション参照)。

-r
--no-file-warnings
     引数 FILE がオープンできないときも、警告メッセージを表示しない (終了ステータスは、それでもやはり 0 以外になる)。

-s[CHAR]
--separator[=CHAR]
     段と段の区切りに 1 個の文字 CHAR を使う。-s オプションを指定したときのデフォルトの CHAR は、-w オプションを同時に指定しなければタブ、指定すれば「なし」である。なお、-s オプションを指定しない場合のデフォルトのセパレータはスペースだ。 -s[char] オプションを使用すると、-w も同時に指定しないかぎり、 3 種の段組みオプション (-COLUMN|-a -COLUMN|-m) のすべてにおいて、行の切り詰めが行われない。これは、POSIX に準拠した仕様である。

-S[STRING]
--sep-string[=STRING]
     出力される段の区切りに、文字列 STRING を使用する。-s オプションが -W/-w オプションに影響を及ぼすのとは異なり、 -S オプションは -W/-w オプションに影響を及ぼさない。また、行の切り詰めや段の整列にも影響しない。-S オプションを指定せずに、 -J オプションを指定すると、pr はデフォルトの出力セパレータであるタブを使用する (訳注: -J 使用時のデフォルトということだと思う)。-S も -J も指定しない場合、pr が区切りに使用するのはスペースである (-S" " と同じこと)。-S だけで、引数の STRING を指定しないと、空文字列 ("") を指定したことになる。

-t
--omit-header
     常とは異なり、各ページにヘッダ (とフッタ) を表示しない。また、ページの最下部を (空行やフォームフィードで) 埋めることもしない。ページ構成は行わないが、入力ファイルにあるフォームフィードは、そのままにしておく。つまり、あらかじめ決めておいたページ分割が、変更されないということだ。-t や -T オプションは、他のオプションと組み合わせて使うと、便利なことがある。たとえば、-t -e4 は、入力ファイルのタブ文字を 4 個のスペースに展開するが、それ以外何の変更も行わない。-t オプションを使用すると、 -h オプションが無効になる。

-T
--omit-pagination
     ヘッダ (とフッタ) を表示しない。さらに、入力ファイルにあるフォームフィードをすべて取り除く。

-v
--show-nonprinting
     非表示文字をバックスラッシュ付きの 8 進数表記で表示する。

-w PAGE_WIDTH
--width=PAGE_WIDTH
     本文を多段組み出力にしたときにのみ、ページの幅を PAGE_WIDTH 文字にする (PAGE_WIDTH のデフォルトは 72 字)。各段の幅が等しくなるようにするため、ページ幅が指定した PAGE_WIDTH より狭くなることがある。多段組みで -w オプションを指定せず、-s[CHAR] オプションだけ指定すると、デフォルトのページ幅が無効になり、行の切り詰めや段の整列も行われなくなる。すなわち、各段の長い行が長いまま結合されてしまうのだ。なお、1 段組みの出力では、 PAGE_WIDTH の指定はできない。以上は、POSIX に準拠した仕様である。

-W PAGE_WIDTH
--page_width=PAGE_WIDTH
     ページの幅を PAGE_WIDTH 文字にする。この指定は、段組みオプションがあってもなくても、有効である。段組みオプションとともに使った場合、各段の幅が等しくなるようにするため、ページ幅が指定した PAGE_WIDTH より狭くなることがある。-J オプションを使用しないかぎり、本文の行が切り詰められる。 3 種の段組みオプション (-COLUMN, -a -COLUMN, -m) と組み合わせて使った場合、段の整列が常に行われる。セパレータを指定するオプションの -S や -s が、 -W オプションを無効にすることはない。デフォルトは 72 文字である。 -W PAGE_WIDTH オプションもなく、段組みオプションも全く指定されていない場合に、行の切り詰めが行われることは絶対にない (下位互換を維持しつつ、よく行われる作業のほとんどに対応するために、そうなっている)。この動作は、-W 72 -J と同じである。なお、ヘッダ行が切り詰められることは絶対にない。

終了ステータス 0 は成功を示し、0 以外の値は失敗を示す。

fold: 入力行を指定された幅に合わせて折り返す
=========================

fold は、各 FILE (- は標準入力を表す) を、長い行は折り返して、標準出力に書き出す。 FILE が指定されていない場合は、標準入力を対象にする。

(訳注: fold の日本語対応は完全ではない。 3 バイトで表現される UTF-8 の漢字やかなは、1 文字 が 3 桁として計算され、画面上では 2 桁分を占める。だから、日本語のテキストが 3 バイトの UTF-8 文字だけで書かれているならば、fold -w 105 で長い行が 1 行 35 字 (70 桁) できちんと折り返される。だが、出力行の長さが不適切だったり、ASCII 文字や 4 バイトの漢字が交じったりすると、行末や行頭で文字化けが生じかねない。もちろん、日本語の禁則処理は期待できない。)

書式:

     fold [OPTION]... [FILE]...

デフォルトでは、fold は 80 桁よりも長い行を折り返す。出力は必要なら何行にも分割されることになる。

fold はデフォルトでは、画面上の桁数を数える。従って、タブは 2 桁以上に数えられるかもしれないし、バックスペースは桁数を減らすことになる。また、復帰文字 (carriage return) は、桁数を 0 にする。

このプログラムでは以下のオプションが使用できる。参照: Common options.

-b
--bytes
     桁数ではなく、バイト数を数える。従って、タブ、バックスペース、復帰文字も、他の文字と全く同じように、それぞれ 1 桁を占めるものとして計算される。

-s
--spaces
     単語境界で折り返す。行は、行の最大長より前にある最後の空白の後ろで折り返される。行にそうした空白がない場合は、通常通り、行の最大長で折り返される。

-w WIDTH
--width=WIDTH
     行の最大長に 80 桁ではなく、WIDTH 桁を使用する。

     互換性のために、fold は古い書式のオプション -WIDTH もサポートしている。新しいスクリプトでは、-w WIDTH の方を使用すべきである。

終了ステータス 0 は成功を示し、0 以外の値は失敗を示す。

ファイルの部分出力
*********

以下のコマンドは、入力の一部を出力する。

head: ファイルの先頭部分を出力する
====================

head は、各 FILE の先頭部分 (デフォルトでは 10 行) を表示する。ファイルが指定されていない場合や、FILE として - が指定されている場合は、標準入力から読み込む。

書式:

     head [OPTION]... [FILE]...

指定された FILE が 2 個以上あると、 head は、次のような 1 行からなるヘッダを出力する。

     ==> FILE NAME <==

このヘッダは、各 FILE の出力の前に置かれる。

このプログラムでは以下のオプションが使用できる。参照: Common options.

-c [-]NUM
--bytes=[-]NUM
     ファイルの先頭数行を表示する代わりに、先頭から NUM バイトを表示する。ただし、NUM の前に - が付いている場合は、各ファイルについて、末尾の NUM バイトを除いたすべてを表示することになる。 NUM は、整数であり、以下に挙げるような何倍かを示す接尾辞を後ろに付けることもできる。接尾辞だけ指定してもよい (訳注: その場合は、1 が前にあるものと見なされる)。

          b  =>            512 ("blocks")
          KB =>           1000 (KiloBytes)
          K  =>           1024 (KibiBytes)
          MB =>      1000*1000 (MegaBytes)
          M  =>      1024*1024 (MebiBytes)
          GB => 1000*1000*1000 (GigaBytes)
          G  => 1024*1024*1024 (GibiBytes)

     T, P, E, Z, Y についても同様。

-n [-]NUM
--lines=[-]NUM
     ファイルの先頭から NUM 行を表示する。ただし、NUM の前に - が付いている場合は、各ファイルについて、末尾の NUM 行を除いたすべてを表示することになる。サイズの乗数接尾辞は、-c オプションの場合と同様である。

-q
--quiet
--silent
     ファイル名を示すヘッダを出力しない。

-v
--verbose
     ファイル名を示すヘッダを常に出力する。

-z
--zero-terminated
     項目の区切りに、改行 (ASCII LF) ではなく、ゼロバイトを使用する。すなわち、入力を ASCII NUL で分離された項目として扱い、出力する各項目の末尾に ASCII NUL を付加する。このオプションは、perl -0, find -print0, xargs -0 などと組み合わせて使用すると、便利なことがある。そうしたコマンドでも、わがままなファイル名を (空白などの特殊文字を含んでいる場合でも) きちんと確実に処理するために、同様なことをしているのである。

head は、互換性を考慮して、-[NUM][bkm][cqv] というオプション指定の古い書式もサポートしている。ただし、この書式が認識されるのは、最初のオプションとして指定されたときだけである。 NUM は 10 進数であり、-c オプションの場合と同様、サイズを示す文字 (b, k, m) を後ろに続けてもよく、また、行数であることを明示する l や、ほかのオプション文字 (cqv) を続けることもできる。標準的なホストで使うことを意図したスクリプトでは、古い書式ではなく、-c NUM や -n NUM を使用するべきである。そのスクリプトが、古い書式にしか対応していないホストでも動作する必要がある場合は、 head を使わないで済ました方が、たいていの場合簡明である。たとえば、head -5 の代わりに、sed 5q を使用するわけだ。

終了ステータス 0 は成功を示し、0 以外の値は失敗を示す。

tail: ファイルの末尾部分を出力する
====================

tail は、各 FILE の末尾部分 (デフォルトでは 10 行) を表示する。ファイルが指定されていない場合や、FILE として - が指定されている場合は、標準入力から読み込む。

書式:

     tail [OPTION]... [FILE]...

指定された FILE が 2 個以上あると、tail は、各 FILE の出力の前に、以下のような 1 行からなるヘッダを出力する。

     ==> FILE NAME <==

tail の出力をさらに処理したい場合は、ファイルヘッダを行頭の見出しに変更すると便利かもしれない。こんなふうにすればよい。

     tail ... |
     awk '
       /^==> .* <==$/ {prefix=substr($0,5,length-8)":"; next}
       {print prefix$0}
     ' | ...

GNU の tail は、出力するデータの量に制限がない (ほかの系統の tail には、制限があるものもある)。また、GNU の tail には、 -r オプション (逆順で表示する) が存在しない。ファイルを逆順にするのは、ファイルの末端部分を表示するのとは、全く別の仕事だからだ。BSD の tail には、-r があるが、バッファの大きさまでのファイルしか逆順にできず、それは通常 32 KiB である。ファイルを逆順にするなら、GNU の tac コマンドの方が、信頼性という点でも、用途の広さという点でも優れている。

このプログラムでは以下のオプションが使用できる。参照: Common options.

-c [+]NUM
--bytes=[+]NUM
     ファイルの末尾数行を出力する代わりに、末尾の NUM バイトを出力する。ただし、NUM の前に + が付いている場合は、各ファイルの末端から NUM バイト目ではなく、先頭から NUM バイト目を始点として出力を開始する。 NUM は、整数であり、以下に挙げるような何倍かを示す接尾辞を後ろに付けることもできる。接尾辞だけ指定してもよい (訳注: その場合は、1 が前にあるものと見なされる)。

          b  =>            512 ("blocks")
          KB =>           1000 (KiloBytes)
          K  =>           1024 (KibiBytes)
          MB =>      1000*1000 (MegaBytes)
          M  =>      1024*1024 (MebiBytes)
          GB => 1000*1000*1000 (GigaBytes)
          G  => 1024*1024*1024 (GibiBytes)

     T, P, E, Z, Y についても同様。

-f
--follow[=HOW]
     ファイルの末端まで達しても、さらに文字を読み込もうとして、無限ループする。たぶん、ファイルのサイズが増加し続けているからである。複数のファイルが指定されている場合、tail は、異なるファイルから出力があるたびに、その出力がどのファイルから来たものかわかるように、ヘッダを表示する。

     このオプションを使ってファイルの追跡をするとき、二つの方法が選択できるが、その違いが現れるのは、追いかけているファイルが消去されたり、名前を変更されたりしたときだけである。もし、増大しつつあるファイルが削除されたあとでも、そのファイルの末尾の追跡を続行したいならば、--follow=descriptor を使用すればよい。これがデフォルトの動作だが、ログファイルを追跡している際には、役に立たない。ログファイルは、ローテートされる (すなわち、消去、または名前を変更されてから、改めてオープンされる) 可能性があるからだ。そうした場合には、--follow=name を使用すれば、指定した名前のファイルを追跡することができる。おそらく追跡には、定期的にその名前のファイルをオープンし直すことで、何らかのプログラムによってファイルが消去されてから再作成されなかったかどうかを確かめるといった方法が、使われることだろう。なお、inotify をベースにした実装では、そうしたケースを処理するのに、ファイルを定期的に再オープンする必要がないことを付記しておく。

     どちらの方法を使った場合でも、追跡中のファイルのサイズが小さくなっていることがわかると、 tail は、ファイルが短縮されたというメッセージを出し、ファイルの末端と改めて判断したところからファイルの追尾を再開する。

     ファイルが消去されたときの tail の動作は、追いかけているものが、名前か (--follow=name)、ディスクリプタか (--follow=descriptor) によって異なっている。名前による追跡の場合、 tail はファイルが消去されたことを検出できるので、その旨メッセージを表示する。このとき、--retry も指定されていると、同じ名前のファイルが再作成されているかどうか、定期的な検査を継続して行う。ディスクリプタを追跡する場合は、ファイルが削除されたり、名前の変更が行われたりしても、 tail はそれを検出しないので、メッセージを出さない。そうしたファイルが、もはや元の名前ではアクセスできなくなっていても、なお増大し続けているということもありえる。

     descriptor や name というオプションの値は、長い方のオプションの形式によってのみ指定できる。-f では指定できない。

     オペランド FILE が全く指定されていず、標準入力が FIFO やパイプである場合は、-f オプションは無視される。また、標準入力が FIFO やパイプである場合は、- という形で指定されたオペランドがあっても、 -f はそれに対して効果を持たない。

     カーネルが inotify をサポートしていると、出力はファイルの変更が引き金になるので、一般に反応がキビキビしている。それに対して、カーネルが inotify をサポートしていないと、tail はチェックごとに 1 秒間スリープするので (このデフォルトを変更するには、--sleep-interval=N を使用する)、出力がやや遅めに感じられたり、断続的に感じられたりするかもしれない。inotify のサポートなしで tail を使用する場合、反応を向上させるには、sleep する間隔を 1 秒以下に設定すればよい。たとえば、次のようなエイリアスを作成するわけだ。

          alias tail='tail -s.1'

-F
     このオプションは --follow=name --retry と同じである。すなわち、ファイルが消去された場合、tail はその名前のファイルをオープンし直そうとする。それに失敗しても、ファイルに再びアクセスできるようになるまで、再オープンを試み続ける。

--max-unchanged-stats=N
     名前によってファイルの追尾を行っているとき、連続して N 回 (デフォルトは n=) 追尾動作を実行しても、その間にファイルに変更がなかった場合に、ファイルを open し、fstat して、そのファイル名と結びついている「デバイス番号/inode 番号」の組み合わせが、今でも前と同じままかどうかを確認する。ローテートを行うログファイルを追跡している場合、この N は、tail がローテートする前に最後の行を表示してから、新しいログファイルに溜まっている行を表示するまでの秒数に、ほぼ等しい。このオプションに意味があるのは、ポーリングを使用して (すなわち、inotify を使わずに)、名前による追跡を行うときだけである。

-n [+]NUM
--lines=[+]NUM
     末尾の  NUM 行を出力する。ただし、NUM の前に + が付いている場合は、各ファイルの末端から NUM 行目ではなく、先頭から NUM 行目を始点として出力を開始する。サイズの乗数接尾辞は、-c の場合と同様である。

--pid=PID
     追跡が名前によって行われていようと、ディスクリプタによって行われていようと、 FILE 引数で指定されたすべてのファイルに書き込みを行うプログラムがたった一つならば、そのプログラムのプロセス番号 PID を指定することができる。そうしておくと、そのプロセスが終了する直後に tail も終了するようになるのだ。これがきちんと動作するのは、書き込みプログラムと tail のプロセスが、同じマシンで動いているときだけである。たとえば、プログラムをビルドするとき、その出力をファイルに保存しながら、ファイルが増大して行くのを見守りたいならば、下記のように make と tail を実行すればよい。そうすれば、ビルドが完了したとき、tail のプロセスも終了する。このオプションを使わない場合は、tail -f のプロセスを自分で止めなければならないだろう。

          $ make >& makerr & tail --pid=$! -f makerr

     使用されていない PID を指定した場合や、 tail が対象とするファイルに書き込んでいるプロセスとは別のプロセスの PID を指定した場合は、 tail は、FILE の増大が止まるずっと前に終了してしまうかもしれないし、実際に書き込んでいるプログラムが終了してしまっても、当分の間終了しないかもしれない。気をつけてほしいが、システムによっては、--pid が使えないことがある。その場合、tail は警告メッセージを出すはずだ。

-q
--quiet
--silent
     ファイル名を示すヘッダを出力しない。

--retry
     指定された名前のファイルを繰り返し何度でもオープンしようとする。このオプションが役に立つのは、ファイルの末尾を追跡している場合がほとんどである (それ以外の場合は、警告メッセージを出す)。

     ファイル・ディスクリプタによって追跡している場合は (すなわち、 --follow=descriptor の場合は)、このオプションは、最初にファイルをオープンするときの動作にしか影響しない。ひとたびオープンに成功してしまえば、tail は、ファイル名ではなく、ファイル・ディスクリプタを追跡することになるからである。

     ファイル名によって追跡している場合は (すなわち、--follow=name の場合は)、tail は、ユーザによって中断 (kill) されるまで、いつまでも繰り返しその名前のファイルを再オープンしようとする。

     このオプションを付けないと、 tail は、ファイルが存在しなくなったり、何かほかの理由でファイルにアクセスできなくなったりすることがあっても、その旨報告するだけで、以後再検査を行うことがない。

-s NUMBER
--sleep-interval=NUMBER
     何秒間隔で追尾・表示動作を行うかを変更する (デフォルトは 1.0 秒間隔)。 tail は動作の繰り返しごとに、指定されたすべてのファイルについて、サイズが変わっていないかどうかのチェックを行う。tail の伝統的な実装では、NUMBER は整数でなければならなかったが、GNU の tail では、任意の浮動小数点数を指定することが可能になっている。 See Floating point.  tail が inotify を使用していると、このポーリング関係の (polling-related) オプションは通常無視される。ただし、--pid=P も一緒に指定されている場合は別で、その場合は、プロセス P が生きているかどうかを、tail が少なくとも NUMBER 間隔でチェックすることになる。

-v
--verbose
     ファイル名を示すヘッダを常に出力する。

-z
--zero-terminated
     項目の区切りに、改行 (ASCII LF) ではなく、ゼロバイトを使用する。すなわち、入力を ASCII NUL で分離された項目として扱い、出力する各項目の末尾に ASCII NUL を付加する。このオプションは、perl -0, find -print0, xargs -0 などと組み合わせて使用すると、便利なことがある。そうしたコマンドでも、わがままなファイル名を (空白などの特殊文字を含んでいる場合でも) きちんと確実に処理するために、同様なことをしているのである。

tail は互換性のために、tail -[NUM][bcl][f] [FILE] という古い用法もサポートしているが、それが認識されるのは、上で説明した用法と衝突しないときだけである。この旧来の書式では、オプションはただ 1 個しか指定できず、ファイルも 1 個までしか指定できない。オプション中の NUM は、省略可能な 10 進数であり、サイズを表す文字 (b, c, l) を後ろに続けて、1 ブロック当たり 512 バイトのブロック数か、バイト数か、行数かを示すことができる。さらに、-f と同じ意味を持つ、f を続けてもよい。

POSIX 1003.1-2001 に準拠していないシステムでは、旧来のオプション書式において、先頭の - を -c や -n オプションの場合と同じ意味で + に置き換えることができる。また、POSIX 1003.1-2001 以前の旧式なシステムでは、旧来の用法と標準的な用法が衝突する場合には、旧来の用法が優先される。なお、そうした動作は、環境変数 _POSIX2_VERSION によってコントロールできる。 (see Standards conformance)。

標準的なホストで使用するためのスクリプトでは、旧来の書式を使わずに、 -c NUM[b], -n NUM オプションや -f オプションの方を使うべきである。そのスクリプトが、旧来の書式にしか対応していないホストでも動作しなければならない場合でも、問題を起こしかねない表現を避けるように書き直すことが、たいていはできるものだ。たとえば、tail -1 の代わりに、sed -n '$p' を使うといった具合である。それさえ不可能な場合は、どちらの書式を使うべきかを判断するために、 if tail -c +1 </dev/null >/dev/null 2>&1; then ... といった条件文をスクリプトで使用すればよい。

作成するスクリプトが標準的な動作を想定している場合でも、 POSIX のバージョンによって動作に違いのある用法には、気を付けた方がよい。たとえば、tail - main.c は避けるべきである。tail main.c と解釈することも、tail -- - main.c と解釈することもできるからだ。 tail -c 4 も避けるべきである。tail -c4 を意味するかもしれないし、 tail -c 10 4 を意味するかもしれない。tail +4 も使わない方がよい。 tail ./+4 の意味にも、tail -n +4 の意味にも取れるからである。

終了ステータス 0 は成功を示し、0 以外の値は失敗を示す。

split: ファイルを分割する。
=================

split は、入力ファイル INPUT を分割して複数の出力ファイルを作成する。各出力ファイルには、INPUT の断片が、連続した形で、あるいは 1 行づつ順番に分配された形で含まれることになる (訳注: 前者は単純な分割であり、後者は後述の「ラウンド・ロビン方式」である。-n オプションを参照)。 INPUT が指定されていない場合や、- である場合には、標準入力から読み込む。

書式:

     split [OPTION] [INPUT [PREFIX]]

デフォルトでは、split は INPUT を 1000 行づつ各出力ファイルに書き込む (最後の断片については、何行であれ残っている行を書き込む)。

出力ファイルの名前は、上記書式の PREFIX (デフォルトでは x) に複数の文字 (デフォルトでは、aa, ab, ...) を続けたものであり、各出力ファイルをファイル名による伝統的なソート順で結合すると、元の入力ファイルが再構成されるようになっている (ただし、-nr/N オプションを指定した場合は除く)。デフォルトでは、split はまず、作成するファイルに 2 文字からなる接尾辞 (訳注: suffix、すなわち上記の aa, ab など) を生成して付け、その接尾辞の 1 番目の文字がアルファベットの最後に達した時点で、接尾辞を 2 文字づつ増やして行く (yz の次は zaaa, zaab, ... という具合)。こうした命名法を使えば、出力ファイルがいくつあっても対応できるし、また --additional-suffix オプションを付けたときでも、出力ファイルが上で述べたような順に並ぶことになるわけだ。 -a オプションが指定されている場合に、出力ファイルの名前が種切れになってしまうと、 split はエラーメッセージを出すが、作成した出力ファイルを消去することはない。

このプログラムでは以下のオプションが使用できる。参照: Common options.

-l LINES
--lines=LINES
     INPUT から LINES 行づつ各出力ファイルに書き込む。 --separator オプションが指定されている場合は、LINES はレコード数の指定になる。

     互換性を考慮して、split は -LINES という古いオプションの書式もサポートしている。新規にスクリプトを書くなら、 -l LINES の方を使うべきである。

-b SIZE
--bytes=SIZE
     INPUT から SIZE バイトづつ各出力ファイルに書き込む。 SIZE は、整数であり、以下に挙げるような何倍かを示す接尾辞を後ろに付けることもできる。接尾辞だけ指定してもよい (訳注: その場合は、1 が前にあるものと見なされる)。

          b  =>            512 ("blocks")
          KB =>           1000 (KiloBytes)
          K  =>           1024 (KibiBytes)
          MB =>      1000*1000 (MegaBytes)
          M  =>      1024*1024 (MebiBytes)
          GB => 1000*1000*1000 (GigaBytes)
          G  => 1024*1024*1024 (GibiBytes)

     T, P, E, Z, Y についても同様。

-C SIZE
--line-bytes=SIZE
     各出力ファイルに、ファイルサイズが SIZE バイトを超過しない範囲で、 INPUT の完全な行をできるだけ多く書き込む。一つの行やレコードの長さが SIZE バイトを越える場合は、複数のファイルに分割される。 SIZE の書式は、--bytes オプションの場合と同じである。 --separator オプションが指定されている場合は、できるだけ多くの行ではなく、できるだけ多くのレコードを書き込むことになる。

--filter=COMMAND
     このオプションを使用すると、各出力は、そのままファイルに書き出されるのではなく、パイプを通して一つづつ、指定されたシェルコマンド COMMAND に引き渡される。COMMAND 中では、環境変数 $FILE を使用するべきであり、この変数には、シェルコマンドを実行するごとに、異なる出力ファイル名が代入される。たとえば、1TiB の圧縮ファイルがあるとしよう。伸長したら、サイズが大きすぎて、ディスクに納まり切らない。しかし、それを分割して、もっと扱いやすいサイズの、それぞれ圧縮したファイルを作らねばならない。そうした課題を解決するには、次のようなコマンドを実行すればよいだろう。

          xz -dc BIG.xz | split -b200G --filter='xz > $FILE.xz' - big-

     圧縮率が 10:1 だとすると、上のコマンドは 20GiB のファイルを 50 個ほど生成することになるだろう。ファイルの名前は、big-aa.xz, big-ab.xz, big-ac.xz などになる。

-n CHUNKS
--number=CHUNKS

     INPUT を CHUNKS 個の出力ファイルに分割する。 CHUNKS の位置には以下のものが指定できる。

          N      INPUT の現在のサイズに基づいて N 個のファイルを生成する。
          K/N    N 個中の K 番目のみを標準出力へ出力する。
          l/N    N 個のファイルを生成する。行やレコードの途中で分割しない。
          l/K/N  同上。ただし、N 個中の K 番目のみを標準出力に出力する。
          r/N    l に似ている。ただし、分配はラウンド・ロビン方式で行う。
                 (訳注： トランプの親がカードを 1 枚づつ子に配るように、
                         入力から 1 行 (1 レコード) づつ各出力ファイルに
                         分配して行く。)
          r/K/N  同上。ただし、N 個中の K 番目のみを標準出力に出力する。

     INPUT を  N 個の「部分 (chunk)」に分けたときに出た余りのバイトは、最後の「部分」に割り振られる。最初に行われる分割のための計算の後で追加されるバイトがあっても、それは捨て去られる (r モードを使用している場合を除く)。

     INPUT の行数が N 行に足りなかったり、INPUT が短縮された場合でも、 N 個のファイルすべてが作成される。

     l モードについて言うと、「部分」の大きさは、「INPUT サイズ / N」前後になる。 INPUT は、まず N 個の同一サイズの区画 (partition) に分割され、余りがあれば、それは最後の区画に割り当てられる。ある行の先頭が、ある区画の内側にある場合、その行は行末まで、その区画に対応するファイルに書き込まれる。行やレコードは、たとえ後続する区画にまではみ出していても分割されないので、書き出されるファイルは、区画のサイズより大きくなることもあれば、小さくなることもある。行やレコードが後続する区画をすっぽり覆ってしまうほど長い場合には、空っぽのファイルができることさえある。

     r モードでは、INPUT のサイズは問題にならない。だから、入力は、たとえば、パイプからであっても構わない。

-a LENGTH
--suffix-length=LENGTH
     使用する接尾辞の長さを LENGTH 文字にする。LENGTH に 0 を指定すると、-a オプションを (すでに指定していた場合でも) 全く指定しなかったのと同じことになり、従って、デフォルトの動作が有効になる。すなわち、接尾辞は、2 文字から始まり、-n や --numeric-suffixes=FROM オプションが指定されていないかぎり、必要になるごとに、2 文字づつ自動的に増えて行く。

-d
--numeric-suffixes[=FROM]
     接尾辞にアルファベットの小文字ではなく、数字を使用する。数字の接尾辞は、 FROM が指定されていれば FROM から、指定されていなければ 0 から数を数えて行く。

     FROM を指定できるのは、長い形式のオプションを使ったときだけである。 FROM を指定すると、split を一回だけ実行する場合に最初の接尾辞を決めたり、それぞれ別々にスプリットする入力に対して相互の接尾辞間をどれくらい離すかを決めたりすることができるが、上で述べた接尾辞の長さを自動的に増やしていく機能は無効になる。そこで、ユーザとしては、99 を越える数字を接尾辞として使えるようにするため、 -a オプションも併せて指定したくなるかもしれない。なお、--number オプションが指定され、しかも、生成されるファイルの数より FROM が小さい場合は、一回かぎりの実行と見なされ、接尾辞に最小限必要な長さが、自動的に割り出される。

     (訳注: 上記の「なお」以下で言っているのは、split -d -n100 some.data などとすると、x00 から x99 までのファイルが作られるが、split --numeric-suffixes=1 -n100 some.data なら、x001 から x100 まで、3 桁の接尾辞を持つファイルが作られるということらしい。しかし、coreutils 8.26 では、split -d -n200 some.data や split --numeric-suffixes=10 -n100 some.data は、 "output file suffixes exhausted" というエラーになる。そして、split -d -n201 some.data や split --numeric-suffixes=10 -n101 some.data なら、実行に成功するのである。よくわからない仕様だと思う。--suffix-length を使って、自分で接尾辞の長さを決めた方が、間違いがない。)

--additional-suffix=SUFFIX
     出力ファイル名の末尾に SUFFIX をさらに追加する。 SUFFIX 中にスラッシュが含まれていてはならない。

-e
--elide-empty-files
     サイズ 0 の出力ファイルができないようにする。そうしたものが生成されることがあるのは、 --number を使ったときである。入力ファイルが (短縮されたりして) 指定された数の出力ファイルを作るには分量が足りない場合や、 1 行が長すぎて、後続する「部分」をすっぽり飲み込んでしまっている場合などがそれに当たる。このオプションが指定されているときでも、出力ファイルの連続番号が、順番に増えていくことに変わりはない。

-t SEPARATOR
--separator=SEPARATOR
     レコード・セパレータとしてデフォルトの改行文字 (ASCII LF) の代わりに、文字 SEPARATOR を使用する。ASCII NUL をセパレータに指定するには、二文字からなる文字列 \0 を使用すればよい。split -t '\0' のようにだ。

-u
--unbuffered
     --number r/... モードにおいて入力を即座に出力する。このモードは、作業にかなり時間がかかるのだ。

--verbose
     各出力ファイルをオープンする直前に、診断メッセージを表示する。

終了ステータス 0 は成功を示し、0 以外の値は失敗を示す。

--number (-n) の動作を理解していただくために、用例をいくつか挙げてみる。

デフォルトでは、1 行が 2 行以上に分割されることがあるのに、注目していただきたい。

     $ seq -w 6 10 > k; split -n3 k; head xa?
     ==> xaa <==
     06
     07
     ==> xab <==

     08
     0
     ==> xac <==
     9
     10

"l/" 修飾子を使用して、行の途中で分割しないようにする。

     $ seq -w 6 10 > k; split -nl/3 k; head xa?
     ==> xaa <==
     06
     07

     ==> xab <==
     08
     09

     ==> xac <==
     10

"r/" 修飾子を使用して、ラウンド・ロビン方式で分配する。

     $ seq -w 6 10 > k; split -nr/3 k; head xa?
     ==> xaa <==
     06
     09

     ==> xab <==
     07
     10

     ==> xac <==
     08

K 番目の「部分」だけ取り出すこともできる。次の例は、33 の「部分」に分け、そのうちの  7 番目だけを取り出して、表示している。

     $ seq 100 > k; split -nl/7/33 k
     20
     21
     22

csplit: ファイルを内容を目印にして分割する。
==========================

csplit は、入力ファイル INPUT を分割して 0 個以上の出力ファイルを生成する。 INPUT が - である場合は、標準入力から読み込む。

書式:

     csplit [OPTION]... INPUT PATTERN...

出力ファイルの中身がどうなるかは、以下で詳しく述べるように、引数 PATTERN によって決まってくる。引数 PATTERN が、入力ファイル中に存在しない行を指している場合は、エラーになる (たとえば、入力の残りの部分に、指定された正規表現にマッチする行がもう存在しない場合)。すべてのパターン・マッチが終わったとき、残っている入力があれば、最後の出力ファイルに書き出される。

デフォルトでは、csplit は、出力ファイルを生成した後で、各出力ファイルに書き込んだバイト数を表示する。

パターン引数 PATTERN には、以下のタイプがある。

N
     入力の最初から N 行目の直前までを含む (つまり、N-1 行目までの) 出力ファイルを作成する (N は正の整数)。繰り返し回数の指定が後に続く場合は、繰り返しごとに、入力ファイルの次の N 行分を含む出力ファイルを作成していく。 (訳注: パターンが N の場合は、あと何回繰り返すかを正確かつ具体的に指定しなければならない。すなわち、回数が多かったり、{*} を指定すると、-k も指定しないかぎり、エラーになり、出力ファイルが作成されない。)

/REGEXP/[OFFSET]
     現在行から、入力ファイル中の次に REGEXP にマッチする行の直前までを内容とする (すなわち、マッチする行は含まない) 出力ファイルを作成する。整数の OFFSET を指定してもよい。指定した場合は、マッチする行にプラス/マイナス OFFSET した行の直前までの入力が (つまり、その行は含まない)、出力ファイルに書き込まれ、書き込まれた次の行から入力の後続部分が始まることになる。

%REGEXP%[OFFSET]
     上記のタイプと同様だが、出力ファイルを作成しない点が異なる。要するに、入力ファイルのその部分は捨てられることになるわけだ。

{REPEAT-COUNT}
     直前に行ったパターンの検索を、さらに REPEAT-COUNT 回繰り返す。 REPEAT-COUNT には正の整数か、アステリスクを指定できる。後者は、入力がなくなるまで、必要なだけ何回でも繰り返すことを意味する。 (訳注: csplit INPUT '/PATTERN_1/' '{3}' '/PATTERN_2/' '{*}' のように使用する。)

出力ファイルの名前は、接頭辞 (prefix、デフォルトでは xx) に接尾辞 (suffix) を続けたものになる。デフォルトの接尾辞は、二桁の 10 進数を 00 から 99 まで順番に増やして行ったものである。いかなる場合でも、出力ファイルを、ファイルの名前によってソートした順番で結合すると、元の入力ファイルが生成されるようになっている。

csplit のデフォルトでは、エラーになった場合や、ハングアップ、割り込み、中止、終了といったシグナルを受け取った場合には、それまでに作成した出力ファイルをすべて消去してから終了する。

このプログラムでは以下のオプションが使用できる。参照: Common options.

-f PREFIX
--prefix=PREFIX
     PREFIX を出力ファイル名の接頭辞として使用する。

-b FORMAT
--suffix-format=FORMAT
     FORMAT を出力ファイル名の接尾辞として使用する。このオプションを指定する場合、接尾辞として指定する文字列には、printf(3) 方式の変換指定が必ず一つは (それも、一つだけ) 含まれていなければならない。変換指定には、形式指定フラグ、フィールド幅、精度指定といった修飾子を付けてもよく、 3 種の修飾子をすべて付けることもできる。フォーマット文字は、バイナリの符号なし整数である引数を、人間に読みやすい形式に変換するものでなければならない。フォーマット文字の d と i は、u の別名であり、u, o, x, X 変換が可能である。FORMAT の全体が (現在の出力ファイルが何番目かという情報とともに) sprintf(3) 関数に引き渡され、出力ファイルの一つ一つに対して、ファイル名に使う接尾辞が順番に作られることになる。なお、このオプションを使用すると、--digits オプションは無視される。

-n DIGITS
--digits=DIGITS
     出力ファイル名に含まれる数字の桁数を、デフォルトの 2 桁から DIGITS 桁にする。

-k
--keep-files
     エラーが起きても、出力ファイルを消去しない。

--suppress-matched
     指定した PATTERN にマッチする行を出力しない。言い換えれば、境界になる行が、分割されたファイルの 2 番目以降の断片の先頭に現れないようにする。 (訳注: PATTERN が正規表現の場合には、境界になる行がファイル中にたとえ 1 箇所しかなくても、その行の表示を抑制するには、csplit --suppress-matched INPUT PATTERN '{*}' などと、繰り返しの指定をする必要があるようだ。)

-z
--elide-empty-files
     サイズ 0 の出力ファイルができないようにする (入力ファイルを各部分に区切る行が、どの部分においても最初の行になることを期待している場合に、このオプションを使わないと、一番目の出力ファイルがたいていサイズ 0 になる)。このオプションが指定されているときでも、出力ファイルの連続番号が 0 から始まって、順番に増えていくことに変わりはない。

-s
-q
--silent
--quiet
     出力ファイルのサイズを表示しない。

終了ステータス 0 は成功を示し、0 以外の値は失敗を示す。

用例を挙げてみよう。まず、練習用に空のディレクトリを作って、そこに移動する。

     $ mkdir d && cd d

次に、1 から 14 まで連続する数を、0 または 5 で終わる行で分割する。

     $ seq 14 | csplit - '/[05]$/' '{*}'
     8
     10
     15

ここで表示された各数字は、csplit が今作成した出力ファイルのサイズである。その出力ファイルの名前をリストする。

     $ ls
     xx00  xx01  xx02

head を使って、内容を見る。

     $ head xx*
     ==> xx00 <==
     1
     2
     3
     4

     ==> xx01 <==
     5
     6
     7
     8
     9

     ==> xx02 <==
     10
     11
     12
     13
     14

次の例では、入力を空行で分割している。

     $ csplit --suppress-matched INPUT.TXT '/^$/' '{*}'

ファイルの要約 (行数、単語数、チェックサム)
***********************

以下のコマンドは、ファイル内容全体を表現する若干の数字を生成する。

wc: 行数、単語数、バイト数を表示する
====================

wc は、指定された各 FILE に含まれる、バイト数、文字数、ホワイトスペース (訳注: 空白、タブ、改行など) で区切られた単語数、改行数を算出する。 FILE が指定されなかった場合や、FILE として - が指定された場合は、標準入力を対象とする。

書式:

     wc [OPTION]... [FILE]...

wc は各ファイルにつき、一行の算出結果を出力する。引数としてファイルが指定されていれば、そのファイル名を数値の後ろに表示する。複数の FILE が指定されている場合は、最後の行で合計を表示し、ファイル名の列に、「合計 (total)」と書き込む。表示される数値の順番は、改行数、単語数、文字数、バイト数、最長行の長さになる。各数値は、フィールドに右詰めで表示され、フィールド間には、少なくとも一個の空白が置かれる。そうすることで、複数の数字とファイル名が、たいていの場合きちんと整列するようになっているのだ。数値の入るフィールドの幅は、入力に応じて変化するので、一定のフィールド幅を当てにするべきではない。ただし、GNU の拡張として、表示される数値がただ 1 個だけの場合は、その数値の頭に空白を入れないことになっている。

デフォルトでは、wc は 3 個の数値を表示する。すなわち、改行数、単語数、バイト数である。オプションによって、特定の数値のみを表示するように指定することもできる。どんなオプションも、それ以前に指定されたオプションを取り消すことはない。従って、

     wc --bytes --words

上記のコマンドは、バイト数と単語数の両方を表示することになる。

--max-line-length を指定すると、wc はファイルごとの最長行の長さを表示する。さらに、複数のファイルが存在する場合は、 (各最長行の合計ではなく) 最長行中の最長のものを表示する。ここで言う行の長さは、画面に表示される桁数のことである。表示桁数の計算は現在のロケールに従って行われ、タブ位置は 8 桁ごとに来るものとされる。

このプログラムでは以下のオプションが使用できる。参照: Common options.

-c
--bytes
     バイト数のみを表示する。

-m
--chars
     文字数のみを表示する。

-w
--words
     単語数のみを表示する。

-l
--lines
     改行数のみを表示する。

-L
--max-line-length
     最長表示行の長さのみを表示する。タブ位置は 8 桁ごとにあるものとする。ワイド・キャラクタについては、表示される幅を考慮する。非表示文字の幅は 0 とする。

--files0-from=FILE
     コマンドラインで名前を指定されたファイルの処理を行わない。その代わりに、ファイル FILE に名前が書き込まれているファイルの処理を行う。なお、FILE 中に書かれている各ファイル名は、ゼロバイト (ASCII NUL) で終端されていなければならない。このオプションは、ファイル名のリストが長すぎて、コマンドライン長の上限を超過してしまいそうなときに、便利である。そうした場合、wc を xargs 経由で実行するのは、望ましくない。なぜなら、xargs はファイルのリストをいくつかの部分に分割して wc に渡すので、wc はリスト全体の合計ではなく、部分リストごとの合計を表示してしまうからである。 ASCII NUL で終端されたファイル名のリストを得る方法の一つは、 GNU find に -print0 を付けて使うことである。 FILE に - を指定すれば、 ASCII NUL で終端されたファイル名を標準入力から読み込むことができる。

     たとえば、カレント・ディレクトリ以下にある、すべての .c ファイルや .h ファイルの内で、最長の行の長さを知るには、次のようにする。

          find . -name '*.[ch]' -print0 |
            wc -L --files0-from=- | tail -n1

終了ステータス 0 は成功を示し、0 以外の値は失敗を示す。

sum: チェックサムとブロック数を表示する
======================

sum は、指定された各 FILE の 16-bit チェックサムを計算する。 FILE が指定されなかった場合や、FILE として - が指定された場合は、標準入力を対象とする。

書式:

     sum [OPTION]... [FILE]...

sum は各 FILE のチェックサムを表示し、その後にファイルのブロック数 (整数に切り上げたもの) を続ける。複数の FILE が指定されていると、ファイル名も表示される (デフォルト)。(--sysv オプションが指定されている場合は、引数に一つでもファイルがあれば、そのファイル名が表示される。)

デフォルトでは、GNU の sum は、BSD の sum と互換性のあるアルゴリズムを使って、チェックサムを計算し、 1 ブロック 1024 バイトのブロック数でファイルサイズを表示する。

このプログラムでは以下のオプションが使用できる。参照: Common options.

-r
     デフォルトの (BSD と互換性のある) アルゴリズムを使用する。このオプションが存在しているのは、System V の sum との互換性のためである。前方に -s オプションも指定されているとき以外、このオプションは効果を持たない。

-s
--sysv
     System V の sum のデフォルトと互換性のあるアルゴリズムを使って、チェックサムを計算し、1 ブロック 512 バイトのブロック数でファイルサイズを表示する。

sum は、互換性のために提供されている。新しいアプリケーションでは、 cksum プログラム (次のセクションを参照) を使う方がよい。

終了ステータス 0 は成功を示し、0 以外の値は失敗を示す。

cksum: CRC チェックサムとバイト数を表示する
===========================

cksum は、指定された各 FILE の CRC (cyclic redundancy check、巡回冗長検査) チェックサムを計算する。 FILE が指定されなかった場合や、FILE として - が指定された場合は、標準入力を対象とする。

書式:

     cksum [OPTION]... [FILE]...

cksum は、各ファイルの CRC チェックサムとバイト数を表示する。また、引数が指定されていない場合を除いて、ファイル名も表示する。

cksum は通常、信頼性の低い方法 (たとえば、netnews) によって転送されたファイルに損傷がないことを確認するために使用される。受信したファイルに対する cksum の出力を、転送元のファイルに対する cksum の出力 (たいてい、配布物中に入っている) と比較するわけである。

CRC のアルゴリズムは、POSIX 規格によって規定されており、BSD や System V の sum のアルゴリズム (直前のセクションを参照) と互換性がない。 CRC アルゴリズムの方が信頼性が高い。

オプションは、--help と --version だけである。 See Common options.

終了ステータス 0 は成功を示し、0 以外の値は失敗を示す。

b2sum: BLAKE2 ダイジェストの表示、または検査をする
================================

b2sum は、指定された各 FILE の 512-bit チェックサムを計算する。 md5sum コマンドと同じ使用法とオプションがサポートされている。 See md5sum invocation.  なお、b2sum では、以下のオプションも使用できる。

-l
--length
     ダイジェストのデフォルトの長さを変更 (短縮) する。長さは bit で指定する。従って 8 の倍数でなければならない。 --check オプションが指定されていると、このオプションは無視される。チェックを行うときは、ダイジェストの長さは自動的に判断されるからである。

md5sum: MD5 ダイジェストの表示、または検査をする
==============================

md5sum は、指定された各 FILE の 128-bit チェックサムを計算する。チェックサムは、指紋 (fingerprint) とか、メッセージ・ダイジェスト (message-digest) とも呼ばれる (訳注: ハッシュ値と呼ばれることもある)。

注意: MD5 ダイジェストは、ファイルの不測の損傷を検知することに関して、単純な CRC (cksum コマンドで使用できる) よりも信頼性が高い。二つのファイルがたまたま同一の MD5 値を持っている確率は、ほとんどゼロだからである。だからと言って、悪意のある改竄に対して安全だと考えてはならない。ある特定の MD5 指紋を持つファイルを見つけ出すことは、現在のところ事実上不可能だと考えられているが、デジタル証明書などのファイルが署名に MD5 ダイジェストを使用しているとき、そうしたファイルに手を加えて、正当に見えるようする方法なら、周知のことだからである。もっと安全なハッシュ値が必要なら、SHA-2 の使用を考慮した方がよい。 See sha2 utilities.

指定された FILE が - の場合や、ファイルが全く指定されなかった場合は、 md5sum は標準入力のチェックサムを計算する。また、md5sum は、ファイルとチェックサムの間に矛盾がないかどうかを判定することもできる。

書式:

     md5sum [OPTION]... [FILE]...

各 FILE に対して md5sum は、デフォルトでは MD5 チェックサム、一個の空白、入力モードがバイナリかテキストかを示すフラグ、それにファイル名を出力する。バイナリモードの指標は * であり、テキストモードの指標は   (空白) である。モードの区別に意味のあるシステムでは、バイナリモードがデフォルトだが、そうでないシステムではテキストモードがデフォルトである。 FILE にバックスラッシュや改行文字が含まれている場合は、出力する行の先頭にバックスラッシュを付け、さらに、ファイル名中の問題のある各文字をバックスラッシュでエスケープする。そうすることで、わがままなファイル名があっても、出力に誤解の余地がないようにしているのだ。 FILE が指定されていなかったり、- という形で指定されている場合は、標準入力から読み込む。

このプログラムでは以下のオプションが使用できる。参照: Common options.

-b
--binary
     各入力ファイルをバイナリとして扱う。すなわち、入力ファイルをバイナリモードで読み込み、出力に * というフラグを付ける。このオプションは --text の反対である。バイナリファイルとテキストファイルを区別しない GNU のようなシステムでは、このオプションは入力モードがバイナリであるとのフラグを付けるだけであり、 MD5 チェックサムの値には影響を及ぼさない。このオプションは、バイナリファイルとテキストファイルを区別する MS-DOS のようなシステムでは、デフォルトである。だだし、読み込みを標準入力から行い、その標準入力が端末であるときは除く。

-c
--check
     各 FILE から (FILE が指定されなかった場合は、標準入力から)、ファイル名とチェックサム情報を読み込み (FILE をチェックサム計算の対象となるデータとして読み込むわけはない)、そのチェックサム情報が、それに対して名前を挙げられているファイルの内容に対応しているかどうかを報告する。このモードの md5sum に対する入力は、たいていの場合、事前に md5sum を実行してチェックサムを生成したときの出力である。入力ファイルの書式は、三種類のものがサポートされている。それは、上記のデフォルトの出力書式、 --tag オプションを付けたときの出力書式、それに BSD の逆順表示モード (reversed mode) の書式であり、最後のものは、デフォルトの書式に似ているが、バイナリとテキストモードを区別する文字を使用しないものである。

     そうした入力ファイルの各行に対して、md5sum は、そこに名前を記載されたファイルを読み込み、その MD5 チェックサムを計算する。そして、算出したメッセージダイジェストが、そのファイル名と同じ行にあるチェックサムと一致しなかった場合は、そのファイルをテストに失敗したものとするのである。両者が一致した場合は、テストにパスしたことになる。デフォルトでは、有効な各行に対して標準出力にメッセージを 1 行づつ書き出し、指名されているファイルがテストにパスしたかどうかを報告する。また、すべてのチェックが完了したとき、テストに失敗したものが一つでもあれば、警告メッセージを標準エラーに出力する。この出力を抑制したければ、--status オプションを使用すればよい。リストされたファイルの中に、オープンできなかったり、読み込めなかったりするものがあった場合や、有効な行に書いてあるチェックサムが対応するファイルの実際の値と一致しなかった場合、それに、有効な行が全く存在しなかった場合は、md5sum は 0 以外のステータスで終了する。それ以外の場合は正常終了することになる。

--ignore-missing
     このオプションが役に立つのは、チェックサムの照合をするときだけである。このオプションを指定すると、チェックサムを照合する際にファイルが存在しなくても、実行に失敗したり、ステータス情報を出したりしなくなる。ダウンロードしたファイルにチェックサムの長大なリストが付いているとき、一部のファイルの照合をするのに便利である。

--quiet
     このオプションが役に立つのは、チェックサムの照合をするときだけである。このオプションを指定すると、チェックサムを照合する際、検査に成功したファイルごとに 'OK' (訳注: 日本語では、「成功」または「完了」) のメッセージを出さなくなる。ただし、ファイルが照合に失敗した場合は、デフォルトと同じ 1 ファイル 1 行の形式で結果を報告する。チェックサムに何らかの不一致があった場合は、失敗を総括した警告メッセージも標準出力に表示する。

--status
     このオプションが役に立つのは、チェックサムの照合をするときだけである。このオプションを指定すると、チェックサムを照合する際、デフォルトの 1 ファイルに付き 1 行の判定メッセージを出さなくなる。また、照合の失敗があっても、それを総括した警告メッセージを出力することもない。とは言え、ファイルのオープンや読み込みに失敗した場合は、やはりそれぞれの診断結果を標準エラーに表示する。リストされたすべてのファイルを読み込むことができ、しかも、すべてのファイルについて、対応する MD5 チェックサムと矛盾がなければ、正常終了する。それ以外の場合は、失敗があったことを示すステータスコードで終了する。

--tag
     BSD スタイルのチェックサムを出力する。つまり、使用したチェックサムのアルゴリズムも表示するということだ。 GNU の拡張として、問題を起こしかねない文字を含むファイル名は、上述したようにエスケープされ、さらに、行の先頭に エスケープの指標に使われたのと同じ \ 文字が付けられる。--tag オプションはバイナリ・モードを意味し、 --text オプションと一緒に使うことは認められていない。そんなことをサポートしても、出力の書式をむやみに繁雑にするだけで、利益はほとんどないからである。

-t
--text
     各入力ファイルをテキストとして扱う。すなわち、入力ファイルをテキストモードで読み込み、出力に   というフラグを付ける。このオプションは --binary の反対である。バイナリファイルとテクストファイルを区別しない GNU のようなシステムでは、このオプションがデフォルトである。ほかのシステムでも、読み込みを標準入力から行い、その標準入力が端末であるときは、デフォルトになる。ただし、--tag が使用されているときに、このモードがデフォルトになることはない。

-w
--warn
     チェックサムを照合する際、MD5 チェックサムを記載した行の書式に正しくないものがあると、その旨警告を発する。このオプションが役に立つのは、チェックされる入力中の、数行を除いたすべての行が、有効なときだけである。

--strict
     チェックサムを照合する際、無効な入力行が 1 行でもあれば、そうした行のすべてについて警告を発したのち、0 以外の終了ステータスで終了する。

終了ステータス 0 は成功を示し、0 以外の値は失敗を示す。

sha1sum: SHA-1 ダイジェストの表示、または検査をする
=================================

sha1sum は、指定された各 FILE の 160-bit チェックサムを計算する。このコマンドの使用法やオプションは、md5sum と全く同じである。 See md5sum invocation.

注意: SHA-1 ダイジェストは MD5 より安全であり、コリジョン (collision、衝突。別のファイルが同一の指紋を持つこと) が起きたという話を聞いたことはない。しかしながら、大量の --- と言っても非現実的なほどではない --- リソースがあれば、コリジョンを作り出せることがわかっている。この理由から、 SHA-1 は、もっと安全な SHA-2 ハッシュ・アルゴリズムに徐々に移行すべきだと、一般に考えられている。 See sha2 utilities.

sha2 utilities: SHA-2 ダイジェストの表示、または検査をする
========================================

コマンド sha224sum, sha256sum, sha384sum, sha512sum は、一まとめにして SHA-2 ハッシュと呼ばれる様々な長さのチェックサムを計算する (それぞれ、224, 256, 384, 512 bits である)。こうしたコマンドの使用法とオプションは、md5sum や sha1sum と全く同じである。 See md5sum invocation.

ソートしたファイルの操作
************

以下のコマンドは、ソートしたファイルを操作 (生成) する。

sort: テキストファイルを並べ替える
====================

sort は、指定されたファイルから読み込んだすべての行に対して、ソート (sort、一定の基準に従った並べ替え)、マージ (merge、データの統合)、比較 (compare) を行う。ファイルが一つも指定されなかった場合や、FILE として - が指定された場合は、標準入力から読み込む。デフォルトでは、sort は結果を標準出力に書き出す。

書式:

     sort [OPTION]... [FILE]...

多くのオプションが、sort が行を比較する方法に影響を及ぼす。そこで、結果が期待どおりでないときは、--debug オプションを使って、どうしてそうなったかを調べてみていただきたい。二つの行の比較は、次のように行われる。sort は、対になる各フィールドを (--key オプションを参照)、コマンドラインで指定された順番で、そのフィールドに結びついた順序関係のオプションに従いつつ比較し、相違が見つかるか、比較するフィールドがなくなるまでそれを続ける。キーとなるフィールドが指定されていない場合は、デフォルトのキーである行全体が比較に使用される。最後に、すべてのキーが同じだったときは、最後の手段として、--reverse (-r) 以外の順序関係のどんなオプションも指定されていないかのように、行全体を比較する。 --stable オプションを指定すると、この最後の手段の比較 (last-resort comparison) を行わないようになり、その結果、すべてのキー・フィールドが等価である行は、互いに対する元の順序がそのまま維持される。 --unique (-u) オプションも、最後の手段の比較を行わないようにする。

別の指定がなされていないかぎり、すべての比較は、LC_COLLATE のロケールによって指定されている文字の照合順序で行われる。 (POSIX 以外のロケールを使用すると (たとえば、LC_ALL を en_US に設定すると)、sort の出力が、見慣れない順序でソートされたものになるかもしれない。その場合は、環境変数 LC_ALL を C にすればよい。注意すべきは、LC_COLLATE だけを設定したのでは、二つの問題が生じてしまうということだ。一つは、LC_ALL も設定されている場合、LC_COLLATE は無効だということ。二つ目は、LC_CTYPE が (LC_CTYPE が設定されていないときは、LANG が) LC_COLLATE と矛盾する値に設定されている場合、動作が未定義だということである。たとえば、LC_CTYPE が ja_JP.PCK であるのに、 LC_COLLATE が en_US.UTF-8 の場合、sort の動作は未定義なのである。) 行末の改行は、比較に当たっては、行の一部として扱われない。入力ファイルの最後のバイトが改行でなければ、GNU の sort は黙って改行を追加する。 GNU の sort では (GNU のすべてのユーティリティについて規定されているとおり)、入力行の長さに上限がない。すなわち、各行に含まれるバイト数に制限がない。

sort には三つの動作モードがある。ソート (これがデフォルト)、マージ、それに、すでにソートされているかどうかのチェックである。動作モードの変更には、以下のオプションを使用する。

-c
--check
--check=diagnose-first
     指定されたファイルがすでにソートされているかどうかをチェックする。ファイル全体がソート済みでない場合は、診断メッセージを出し、順番から外れている最初の箇所を示してから、ステータス 1 で終了する。ファイルがソート済みの場合は、正常終了する。入力ファイルは、1 個しか指定できない。

-C
--check=quiet
--check=silent
     指定されたファイルがすでにソート済みだったら、正常終了する。さもなければ、ステータス 1 で終了。入力ファイルは、1 個しか指定できない。このオプションは -c と同様だが、診断メッセージを出さない点が異なる。

-m
--merge
     指定された複数のファイルを一つのグループとしてソートすることでデータの統合を行う。各入力ファイルは、必ずそれぞれがソート済みでなければならない。マージモードの代わりにソートモードを使えば、そうした条件なしで、ソートとマージを行うことができる。マージモードがあるのは、それが使える場合は、その方が高速だからである。

終了ステータス:

     0: エラーが起きなかった。
     1: -c や -C を付けて実行した際に、入力がソートされていなかった。
     2: エラーが起きた。

環境変数 TMPDIR が設定されていれば、sort はその値をテンポラリ・ファイルを置くディレクトリとして /tmp の代わりに使用する。 --temporary-directory (-T) オプションは、環境変数よりさらに優先される。

以下に挙げるオプションは、出力する行の順序に影響を与える。こうしたオプションは、グローバルなオプションとして指定することもできるし、キーとなる特定のフィールドに対してのみ働くように指定することもできる。キーとなるフィールドが全く指定されていない場合は、グローバルなオプションが行全体の比較に使用される。キー・フィールドの指定がある場合は、グローバルなオプションは、キー・フィールドのうち、それ自身のオプションが特に指定されていないフィールドに継承される。 POSIX 以前の sort のバージョンを使用している場合、グローバルなオプションが効果を持つのは、それより後で指定されるキー・フィールドに対してだけなので、移植を考慮したシェルスクリプトでは、グローバル・オプションを最初に指定した方がよい。

-b
--ignore-leading-blanks
     各行中でソートに使うキーを捜すときに、文字の前にある空白を無視する。デフォルトの空白は、スペースまたはタブだが、LC_CTYPE のロケールによっては違うかもしれない。なお、次のことに留意してほしい。空白は、使用しているロケールの照合ルールによっては無視されることがあるが、このオプションを指定しておかないと、-k オプションで指定されるキー中の文字の位置に関して、空白が意味を持つことになる。

-d
--dictionary-order
     電話帳 (phone directory) 順にソートする。すなわち、ソートする際にアルファベット、数字、空白以外のすべての文字を無視する。デフォルトのアルファベットと数字は ASCII のそれであり、空白はスペースまたはタブだが、後者は LC_CTYPE のロケールによっては違うかもしれない。

-f
--ignore-case
     アルファベットの小文字を、一回すべて対応する大文字に直してから、比較する。その結果、たとえば、b と B は等価なものとしてソートされる。どの文字がどのタイプに属するか (訳注: たとえば、大文字か小文字か) を決めているのは、LC_CTYPE のロケールである。--unique オプションと一緒に使用したとき、小文字を使っている等価な行があると、その小文字の行は捨てられることになる。(大文字を使っている等価な行の方を捨てる方法は、現在のところ存在しない。(--reverse オプションがあっても、それが効果を発揮するのは、小文字の行が捨てられた後の最終結果に対してだけなのだ。)) (訳注: 実際の動作はこの説明と少し違う。最近の sort では、 --unique と併せて使用した場合、小文字を使っている行が捨てられるのではなく、等価な行のうち、最初に現れた行が残り、それ以外のすべてが捨てられるようである。)

-g
--general-numeric-sort
--sort=general-numeric
     各行の先頭部分を倍精度浮動小数点数 (long double-precision floating point number) に変換して、数値としてソートする (訳注: 実際には、各行の先頭と言うより、比較される各フィールドの先頭部分を対象にする)。 See Floating point.  オーバーフロー、アンダーフロー、変換エラーが起きても、通知しない。行の並ぶ順番は以下のようになる。

       * 数字で始まっていない行 (すべて同じ数値と見なされる)。

       * NaN (IEEE の浮動小数点演算で使う ``Not a Number'' を表す値) を一貫した、ただし、マシンに依存する順番で並べる。

       * マイナスの無限大。

       * 有限数を数値として昇順で並べる (-0 と +0 は等価とする)。

       * プラスの無限大。

     このオプションを使うのは、他に方法がないときのみにすること。処理速度が --numeric-sort (-n) よりずっと遅いし、浮動小数点数に変換するとき、情報を失う恐れがあるからだ。

-h
--human-numeric-sort
--sort=human-numeric
     数値としてソートする。その際、ソートを、まず数が正か負かによって行い (負の数、ゼロ、正の数の順)、次に SI 接尾辞 によって行い (接尾辞なし、k や K、そして MGTPEZY の順  see Block size)、最後に数値によって行う。たとえば、1023M は 1G の前に来る。 SI 接尾辞として M(メガ) は G (ギガ) の前になるからだ。つまり、このオプションでソートする対象は、接尾辞の意味が 1000 の累乗か、1024 の累乗かを問わず、一貫したやり方で、数値の規模にもっともふさわしい接尾辞を付けられている数値である。従って、このオプションは、df, du, ls などのコマンドに --human-readable や --si オプションを付けて実行したときの、一回分の出力をソートするのに用いられる。数値の書式は、--numeric-sort の場合と同じであり (訳注: すなわち、数値の前に付けた + 符号を理解しない)、 SI 接尾辞は、数値の後ろに直接続いていなければならない。なお、numfmt コマンドを使用することも考慮していただきたい。numfmt を使用すれば、数値をソートした後で、人間に読みやすい形に整形し直すことができるので、たいていの場合 sort の対象に、より精密な数値を使うことが可能になるからだ。

-i
--ignore-nonprinting
     表示できない文字を無視する。どの文字がどのタイプに属するかを決めているのは、 LC_CTYPE のロケールである。より強力なオプションである --dictionary-order (-d) が一緒に指定されていると、このオプションは効果を持たない。

-M
--month-sort
--sort=month
     比較する部分の先頭が、0 個以上の空白に続いて、月名の短縮形になっているとき、すべての文字を大文字に直して JAN < FEB < ... < DEC の順序で比較する。月名として無効な名前は、有効な月名より前に置かれる。月名のつづりを決めているのは、LC_TIME カテゴリのロケールである (訳注: だから、英語の月名によってソートするには、ロケールを英語か C にしておく必要がある)。デフォルトの空白は、スペースまたはタブだが、 LC_CTYPE のロケールによっては違うかもしれない。

-n
--numeric-sort
--sort=numeric
     数値としてソートする。数値は行頭から始まり (訳注: 比較する位置が指定されていれば、実は行頭でなくてもよい)、任意個の空白、必要なら - 符号、それに、0 個以上の数字から構成される。数値は、区切り記号で 3 桁づつ区切られていてもよく、小数点記号と 0 個以上の数字が続いていてもよい。数字がない場合は、0 と見なされる。小数点記号や桁区切りの記号を規定しているのは、 LC_NUMERIC のロケールである。デフォルトの空白は、スペースまたはタブだが、 LC_CTYPE のロケールによっては違うかもしれない。

     比較は厳密であり、丸めによるエラーはない。

     このオプションは、数値に前置した + 符号や、指数表記を理解しない。そうした文字列を数値として比較するには、--general-numeric-sort (-g) を使用するべきである。

-V
--version-sort
     バージョン名とバージョン番号によってソートする。標準用法のソートと動作が似ているが、 10 進数の数字が連続する各部分をインデックス番号やバージョン番号と見なし、 (文字列としてではなく) 数値として取り扱う点が違う。 (see Details about version sort.)

-r
--reverse
     比較の結果を逆順にする。その結果、出力ではより大きなキーの値を持つ行が、後ではなく、先に表示される。

-R
--random-sort
--sort=random
     ソートを行うのに、入力中のキーをハッシュしてから、そのハッシュ値をソートするという方法を用いる。ハッシュ関数はランダムに選択する。その際、衝突 (collision) が絶対起きないように関数を選択するので、値の違うキーは必ず違うハッシュ値を持つようになる。これは、入力のランダムな並び替えに似ているが (see shuf invocation)、同じ値を持つキーは一緒に並べるという点が、異なっている。

     ランダムソートを行うフィールドが複数指定されている場合は、ランダムに選択された一つの同じハッシュ関数が、すべてのフィールドで使用される。フィールドごとに別のランダムなハッシュ関数を使うようにするには、 sort を複数回呼び出せばよい。

     ハッシュ関数の選択は、 --random-source オプションの影響を受ける。

その他のオプション。

--compress-program=PROG
     テンポラリ・ファイルを PROG というプログラムで圧縮する。

     PROG プログラムは、引数が一つも存在しない場合に、標準入力を圧縮して標準出力に書き出し、 -d オプションの指定があれば、標準入力を展開して標準出力に書き出すものでなければならない。

     PROG が 0 以外のステータスで終了した場合は、エラーメッセージを出して、sort の実行を中止する。

     PROG の指定中でホワイトスペース (訳注: 空白、タブ、改行など) やバックスラッシュ文字を使ってはならない。そうした文字は、将来の使用のために、予約されている。

--files0-from=FILE
     コマンドラインで名前を指定されたファイルの処理を行わない。その代わりに、ファイル FILE に名前が書き込まれているファイルの処理を行う。なお、FILE 中に書かれている各ファイル名は、ゼロバイト (ASCII NUL) で終端されていなければならない。このオプションは、ファイル名のリストが長すぎて、コマンドライン長の上限を超過してしまいそうなときに、便利である。そうした場合、sort を xargs 経由で実行するのは、望ましくない。なぜなら、xargs はファイルのリストをいくつかの部分に分割して sort に渡すので、sort はリスト全体のソートした結果ではなく、部分リストごとのソートした結果を表示してしまうからである。 ASCII NUL で終端されたファイル名のリストを得る方法の一つは、 GNU find に -print0 を付けて使うことである。 FILE に - を指定すれば、 ASCII NUL で終端されたファイル名を標準入力から読み込むことができる。

-k POS1[,POS2]
--key=POS1[,POS2]
     行中の POS1 から POS2 までの部分 (両者を含む) を、ソートの対象となる場所として指定する。POS2 が省略されている場合は、 POS1 から行末までがソートの対象になる。

     最も単純な形の場合、POS で指定するのは、何番目のフィールドかということである (1 から数える)。フィールドは 1 個以上の空白文字によって区切られるが、デフォルトでは、そうした空白文字は比較するとき各フィールドの先頭に含まれることになる。空白文字の扱い方を調整する方法については、-b や -t オプションの説明をご覧いただきたい。

     より一般的に言うと、各 POS は、F[.C][OPTS] という形式を取る。 F は、比較に使用するフィールドは何番目かということであり、 C は、そのフィールドの始めから数えて何番目の文字かということである。フィールドや文字の位置は、1 から数える。なお、POS2 の文字の位置として 0 を指定すると、そのフィールドの最後の文字を指すことになる。.C が、POS1 で省略されている場合は、デフォルトの 1 (フィールドの最初の文字) を指定したことになり、POS2 で省略されている場合は、デフォルトの 0 (フィールドの最後の文字) を指定したことになる。 OPTS は順序関連のオプションであり、これを指定することで、各キーを異なったルールでソートすることが可能になる。詳細については後述しているので、参照していただきたい。なお、キーは複数のフィールドにまたがることができる。

     たとえば、二番目のフィールドでソートするには、--key=2,2 (-k 2,2) を使用する。後述部分で、キーについてさらに説明し、用例ももっとたくさん挙げているので、ご覧になっていただきたい。また、--debug オプションの説明もご覧になるとよい。--debug オプションを使うと、行中のどの部分がソートに使用されているかが明らかになる。

--debug
     各行のソートに使われている部分を強調表示する。また、使用法に問題がありそうなときは、標準エラーに警告メッセージを出す。

--batch-size=NMERGE
     一度にマージする入力ファイルの数を多くても NMERGE 個までとする。

     NMERGE 個を越える入力ファイルをマージしなければならない場合、sort は NMERGE 個のファイルからなるグループを作ってマージし、その結果をテンポラリ・ファイルに保存する。そして、今度はそれを入力として使用して、後に続くマージを行うのである。

     NMERGE の値が大きいと、実行速度が向上し、ハードディスクの一時的な使用が減るかもしれないが、その分、メモリの使用量と I/O が増加する。逆に、NMERGE の値が小さいと、メモリに対する要求と I/O は減少するかもしれないが、その分、ハードディスクの一時的な使用が増え、実行速度が低下することになる。

     NMERGE の値は、2 以上でなければならない。デフォルトの値は 16 だが、これは実装次第なので、将来は変わるかもしれない。

     NMERGE の値は、オープンできるファイル・ディスクリプタの上限によって制限されているかもしれない。 ulimit -n や getconf OPEN_MAX コマンドを使えば、使用しているシステムの上限を知ることができる。ただし、そうした上限がさらに小さくなっていることもあり、使用中のプログラムがすでにファイルをいくつかオープンしている場合や、オープンできるファイルの数についてオペレーティング・システムに他の制限がある場合が、それに当たる。NMERGE がリソースの上限を越えているときは、 sort は警告メッセージを出さずに、より小さい値を使用する。

-o OUTPUT-FILE
--output=OUTPUT-FILE
     出力を標準出力ではなく、OUTPUT-FILE に書き出す。通常、sort は、入力をすべて読み込んでから、OUTPUT-FILE をオープンする。従って、sort -o F F や cat F | sort -o F といったコマンドを使って、ファイルを直接書き変えるやり方でソートをすることが可能だ。とは言え、他の用途に使用されていないファイルに出力する方が、おおむね安全である。ファイルを直接書き変えるやり方でソートしている最中に、システムがクラッシュしたり、 sort が入出力エラーなど、深刻なエラーに遭遇したりすると、データが失われてしまいかねないからだ。また、--merge (-m) オプションを指定した場合は、sort は、入力をすべて読み込む前に、出力ファイルをオープンするかもしれないので、 cat F | sort -m -o F - G といったコマンドは安全ではない。 cat が F の読み込みを済ます前に、sort が F への書き込みを始めてしまうかもしれないからだ。

     比較的新しいシステムでも、環境変数 POSIXLY_CORRECT を設定している場合は、たとえば sort F -o F のように、入力ファイルの後に -o オプションを置くことはできない。移植を考慮したスクリプトでは、 -o OUTPUT-FILE を入力ファイルの前で指定するべきである。

--random-source=FILE
     FILE をランダムデータのソースとして使用する。そのランダムデータは、 -R オプションでどのランダムハッシュ関数を使うかを決めるのに使用される。 See Random sources.

-s
--stable

     最後の手段の比較 (last-resort comparison) を行うのを止めて、sort を入力順尊重 (stable) にする。このオプションは、フィールド指定オプションや、 --reverse (-r) 以外のグローバルな順序関係のオプションが指定されていなければ、効果を持たない。

     (訳注: いわゆる stable sort (普通、安定ソート、固定ソートと訳される) である。たとえば、-b オプションを使って、先行する空白を無視して比較した場合に、等価となる行があったとしよう。通常では、それでも、最後の手段の比較によって、先行する空白の有無も考慮に入れた行全体の比較が行われ、等価な行に順序を付けることになるが、--stable オプションが指定されていると、それをしないので、等価な行は入力されたときの順序で出力される)。

-S SIZE
--buffer-size=SIZE
     指定された SIZE のメインメモリをソート用のバッファとして使用する。デフォルトでは、SIZE は 1024 バイトを 1 単位とする数値である。% を後ろに付けると、SIZE は、物理メモリの何パーセントの意味になる。後置するのが K ならば、SIZE は 1024 倍され (デフォルトと同じ)、 M なら 1,048,576 倍、G なら 1,073,741,824 倍される。 T, P, E, Z, Y の後置も、同じ理屈である。 b を後置すると、SIZE はバイト数と見なされ、掛け算は行われない。

     このオプションを指定すると、sort は作業を始めるとき、デフォルトよりも大きかったり、小さかったりするソート用のバッファを使用することになり、そのために動作速度が向上することがある。とは言え、このオプションは起動直後のバッファサイズにしか影響を持たない。 sort が SIZE を越える入力行に出会うと、バッファのサイズは SIZE 以上に拡大されるからである。

-t SEPARATOR
--field-separator=SEPARATOR
     各行でソートに使うキーを探すとき、文字 SEPARATOR をフィールド・セパレータとして使用する。デフォルトでフィールドを区分するのは、非空白文字と空白文字の間の空文字列である。デフォルトの空白は、スペースとタブだが、LC_CTYPE のロケールによっては、違うかもしれない。

     たとえば、入力行が  foo bar だったとしよう。sort はこれを foo と  bar のフィールドに分割する。フィールド・セパレータは前後どちらのフィールドにも属さないことになっている。そこで、sort -t " " を使用した場合は、同じ入力行が、空っぽのフィールド、 foo、それに bar という 3 個のフィールドを持つことになる。とは言え、キー・フィールドが、-k 2 のように、行末まで続く場合や、 -k 2,3 のように、範囲からなる場合は、範囲の両端の間に存在するフィールド・セパレータは、キー・フィールド中にそのまま保持される。

     ASCII NUL をフィールド・セパレータに指定するには、二文字からなる文字列 \0 を使用すればよい。sort -t '\0' のようにだ。

-T TEMPDIR
--temporary-directory=TEMPDIR
     テンポラリファイルの置き場所にディレクトリ TEMPDIR を使用する。この指定は、環境変数 TMPDIR に優先する。このオプションを二回以上指定すると、テンポラリファイルの置き場所として、指定されたすべてのディレクトリが使用されることになる。大規模なソートやマージを行って、I/O が足枷になる場合、このオプションを使って、別のディスク上にあり、別のコントローラを使用している複数のディレクトリを指定すると、実行速度が向上することがよくある。

--parallel=N
     平行して実行するソートの数を  N に設定する。デフォルトでは、 N は、利用できるプロセッサーの数になっている。ただし、上限は 8 であり、これは、それ以上にしても、速度の向上が頭打ちになるからだ。 N 個のスレッドを使用すると、メモリの使用量が log N 倍になることにも注意していただきたい。参照 nproc invocation.

-u
--unique

     通常は、等価と評価される複数の行の内、最初のもののみを出力する。 --check (-c または -C) オプションが指定されている場合は、等価と評価される行が、2 行連続していないかをチェックする (訳注: 等価な行の連続があると、終了ステータスが 1 になる)。

     また、このオプションを指定すると、デフォルトでは実行する、最後の手段の比較を行わなくなる。

     コマンド sort -u と sort | uniq は等価である。しかし、その等価性は、sort に何か他のオプションが付いたときにまでは及ばない。たとえば、sort -n -u は、唯一性のチェックをするとき、行頭にある数字の並びの値しか調べないが、 sort -n | uniq の方は、行全体を検査するのである。See uniq invocation.

-z
--zero-terminated
     項目の区切りに、改行 (ASCII LF) ではなく、ゼロバイトを使用する。すなわち、入力を ASCII NUL で分離された項目として扱い、出力する各項目の末尾に ASCII NUL を付加する。このオプションは、perl -0, find -print0, xargs -0 などと組み合わせて使用すると、便利なことがある。そうしたコマンドでも、わがままなファイル名を (空白などの特殊文字を含んでいる場合でも) きちんと確実に処理するために、同様なことをしているのである。

sort の従来の (すなわち BSD と System V の) 実装では、いくつかのオプションの解釈が互いに異なっていた。とりわけ、-b, -f, -n についてそうだった。 GNU の sort は、POSIX 規格の動作に従っており、これは、たいていの場合 (常にではない！)、System V の動作と同じである。POSIX によると、-n はもはや -b を自動的に設定しない。そこで、動作の一貫性のために、-M も同様に変更した。この変更によって、フィールドを指定するとき、文字の位置がどこを指すかが、微妙なケースでは変わってくるかもしれない。これに対する唯一の対処法は、明示的に -b オプションを指定することである。

-k によってソート・フィールドを指定するとき、その位置指定の後ろにオプション文字 MbdfghinRrV のうち任意のものを付けることができる。その場合、そのフィールドは、グローバルな順序関係のオプションを一切引き継がないことになる。 -b オプションは、フィールド限定のオプションとしては、フィールド指定の開始位置と終端位置の片方、あるいは両方に付けることができるが、グローバル・オプションから継承した場合は、両方に付いていることになる。入力行が、行頭やフィールド間に複数の空白を含んでいる可能性があって、しかも -t を使っていない場合は、-k を使用するとき、-b と組み合わせるか、先行する空白を暗黙のうちに無視するオプション (すなわち Mghn) と組み合わせるのが普通だ。そうしないと、フィールドにある先行する空白の数の違いのせいで、結果がわけのわからないものになりかねないからである。

ソートフィールド指定の開始位置が、行末より後ろや、終端側のフィールドより後ろに来てしまうと、そのフィールドは空になる。-b オプションを指定した場合、フィールド指定の .C の部分は、そのフィールドの最初の非空白文字から数えることになる。

POSIX 1003.1-2001 に準拠していないシステムの sort では、ソート・キーの指定に、+POS1 [-POS2] という 0 から数える旧来の書式が使用できる。 sort +A.X -B.Y という旧来のコマンドは、もし Y が 0 であるか、指定されていない場合は、 sort -k A+1.X+1,B と同じである。それ以外の場合は、sort -k A+1.X+1,B+1.Y と同じだ。

(訳注: 旧来の書式と新しい書式の違いは、フィールドやフィールド中の文字の位置を 0 から数えるか、1 から数えるかだけではない。終端指定の位置が、旧来の書式ではキー・フィールドに含まれないのに対し (つまり、その直前までなのに対し)、新しい書式では含まれるという違いもある。そこで、上のようになる。なお、旧来の書式であれ、新しい書式であれ、デフォルトのフィールド・セパレータは、「非空白文字と空白文字の間の空文字列」であることに注意していただきたい。)

この旧来の動作は、環境変数 _POSIX2_VERSION を使えば、コントロールすることができる (see Standards conformance)。また、POSIXLY_CORRECT が設定されていないときに、-POS2 が存在する旧来の書式を使っても、有効になる。

標準的なホストで使用することを意図したスクリプトでは、旧来の書式は使わずに、 -k の方を使用するべきである。たとえば、sort +2 は使わない方がよい。 sort ./+2 と解釈されるか、sort -k 3 と解釈されるか、わからないからである。そのスクリプトが、旧来の書式にしか対応していないホストでも動作しなければならないのなら、スクリプト中で if sort -k 1 </dev/null >/dev/null 2>&1; then ... といったテストを行って、どちらの書式を使うべきかを判断すればよい。

用例をいくつか挙げて、オプションの様々な組み合わせを説明する。

  * 数値としてソートし、降順に (つまり、通常の逆に) 並べる。

          sort -n -r

  * 同時にソートを 4 つまで行う。バッファサイズを 10M にする。

          sort --parallel=4 -S 10M

  * 1 番目と 2 番目のフィールドを無視し、さらに 3 番目のフィールドの先頭の空白も無視して、アルファベット順に並べる。ここで使っているキーは一つであり、それは 3 番目のフィールドの最初の非空白文字に始まって、各行の末尾まで続くすべての文字からなっている。

          sort -k 3b

  * 2 番目のフィールドを数値としてソートし、同点の決着を付けるために、 5 番目のフィールドの 3 番目と 4 番目の文字をアルファベット順でソートする。フィールドの区切りには : を使用する。

          sort -t : -k 2,2n -k 5.3,5.4

     ここで注意していただきたいが、もし -k 2,2n の代わりに -k 2n と書いたなら、sort は、2 番目のフィールドに始まり、行末まで続くすべての文字を、主キー (primary key) として、それも「数値」のキーとして使用したことだろう。 sort を実行するたいていの場合について言えることだが、複数のフィールドにまたがるキーを数値として使用しても、期待する結果は得られないものである。

     もう一つ注意していただきたい。上の例では、n 修飾子を最初のキーのフィールド終端指定に付けている。これは、-k 2n,2 とか -k 2n,2n とか指定しても、同じことだったろう。b を除くすべての修飾子は、キー指定のフィールド開始側に付けるか、フィールド終端側に付けるか、あるいは、その両方に付けるかにかかわりなく、付けられた「キー・フィールド全体」に適用されるのである。

  * パスワードファイルを 5 番目のフィールドでソートする。このとき、先頭の空白は無視する。5 番目のフィールドが同じ値になる行については、 3 番目のフィールドのユーザ ID 番号でソートする。フィールドの区切りは、: という文字である。

          sort -t : -k 5b,5 -k 3,3n /etc/passwd
          sort -t : -n -k 5b,5 -k 3,3 /etc/passwd
          sort -t : -b -k 5,5 -k 3,3n /etc/passwd

     この三つのコマンドは同じ働きをする。 1 番目のコマンドは、最初のキーの開始位置では先行する空白を無視し、二番目のキーを数値としてソートするように指定している。他の二つのコマンドは、グローバル・オプションは修飾子がないソート・キーによって継承されるという特性を利用している。この場合、継承がうまく働くのは、-k 5b,5b と -k 5b,5 が同じことだからだ (訳注: 「-b オプションは ... グローバル・オプションから継承した場合は、(開始位置と終端位置の) 両方に付いていることになる」ので、3 番目のコマンドは、-k 5b,5b と指定するのと事実上等しい)。両者が同じになるのは、.C という文字位置を欠いたフィールド終端の指定では、先頭の空白をスキップしてもしなくても、終端位置は変わらないからである。

  * 一群のログファイルをソートする。主キーとして IPv4 アドレスを使用し、副キーとしてタイムスタンプを使用する。二つの行の主キーと副キーが全く同じ場合は、入力されたときと同じ順番で、その行を出力する。ログファイルは、次のような行からなっている。

          4.150.156.3 - - [01/Apr/2004:06:31:51 +0000] message 1
          211.24.3.231 - - [24/Apr/2004:20:17:39 +0000] message 2

     フィールドは、ただ 1 個の空白で区切られている。 IPv4 アドレスのソートは辞書順 (lexicographically) で行う。たとえば、212.61.52.2 は 212.129.233.201 の前に来る。 61 は 129 よりも小さいからだ。

          sort -s -t ' ' -k 4.9n -k 4.5M -k 4.2n -k 4.14,4.21 file*.log |
          sort -s -t '.' -k 1,1n -k 2,2n -k 3,3n -k 4,4n

     この例の場合は、sort を一回起動するだけでは、ことがすまない。日付が空白 1 個のすぐ後に置かれているだけなのに対して、 IPv4 の構成要素は . で区切られているからである。そこで、作業を分割し、 sort を 2 回起動している。1 回目はタイムスタンプでソートし、 2 回目は IPv4 アドレスでソートするわけだ。タイムスタンプは、年、月、日のフィールドの順番でソートし、最後に、時・分・秒のフィールドでソートしているが、それは -k オプションを使って、各フィールドを分離することで実現している。時・分・秒を除いて、各キー・フィールドの終端を指定する必要はない。 n や M 修飾子は、フィールドの先頭にある数値や月名の短縮形に基づいてソートを行うが、そうしたものは、フィールドの境界を越えられないからである。IPv4 アドレスのソートは、辞書順で行っている。なお、二回目のソートで -s を使っているのは、主キーで一ヶ所にまとめられる行が、副キーによってソートされているようにするためである。それに対して、一回目のソートで  -s を使っているのは、二つのソートの組み合わせ全体を入力順尊重 (stable) にするためだ。

  * アルファベットの大文字小文字の違いを無視してソートし、その順番で tags ファイルを作成する。

          find src -type f -print0 | sort -z -f | xargs -0 etags --append

     この例では、-print0, -z, -0 といったオプションを使っている。そのため、空白などの特殊文字を含んでいるファイル名が、ソート操作によって分断されることがない。

  * 慣用句 DSU (Decorate Sort Undecorate) の手法 (訳注: 指標を付けて、ソートして、指標を取る) を採用して、短いものから長いものへと、行を並べる。

          awk '{print length, $0}' /etc/passwd | sort -n | cut -f2- -d' '

     一般に、あるデータが sort コマンドでは直接ソートできないとか、効率が悪いというとき、そうしたデータをソートするのに、この手法が役に立つ。

  * ディレクトリをランダムな順番でで並べる。ただし、各ディレクトリ内のファイルについては、その順番を維持する。一例を挙げると、この方法で演奏リストを作成すれば、アルバムはシャッフルするけれど、各アルバム内の曲は通常のソート順で演奏するといったことが可能になる。

          ls */* | sort -t / -k 1,1R -k 2,2

shuf: テキストをシャッフルする
==================

shuf は、入力された行をランダムに並べ替えてから出力することによって、入力のシャッフルを行う。どの並び替えが出力されるかは、確率的に等しい。

書式:

     shuf [OPTION]... [FILE]
     shuf -e [OPTION]... [ARG]...
     shuf -i LO-HI [OPTION]...

shuf には三つの動作モードがあり、それぞれ、入力行をどこから取得するかが違っている。デフォルトでは、標準入力から行を読み込む。以下のオプションは、動作モードを変更する。

-e
--echo
     コマンドラインの各オペランドを入力行として扱う。

-i LO-HI
--input-range=LO-HI
     LO から HI の範囲の符号なしの 10 進整数を 1 行に 1 個含むファイルから入力があったかのように動作する。

shuf の他のオプションは、どの動作モードでも、その動作に影響を与える。

-n COUNT
--head-count=COUNT
     最大でも COUNT 行までしか出力しない。デフォルトでは、入力されたすべての行を出力する。

-o OUTPUT-FILE
--output=OUTPUT-FILE
     出力を、標準出力ではなく、OUTPUT-FILE に書き出す。shuf は、入力をすべて読み込んでから、OUTPUT-FILE をオープンする。従って、 shuf -o F <F や cat F | shuf -o F というコマンドを使って、ファイルを直接書き変える形でシャッフルしても安全である。

--random-source=FILE
     ランダムデータのソースとして  FILE を使用する。そのランダムデータはどんな並べ替えになるかを決めるのに使用される。 See Random sources.

-r
--repeat
     値の反復出力を行う。別の言い方をすると、置き換えるものについてそのつど選択を行う。このオプションを使用した場合、出力は入力を並び替えたものになるのではない。そうではなく、各出力行がすべての入力からランダムに選ばれるのである。このオプションは、たいてい --head-count と組み合わせて使用する。 --head-count を指定しないと、shuf はいつまでも出力を続けることになる。

-z
--zero-terminated
     項目の区切りに、改行 (ASCII LF) ではなく、ゼロバイトを使用する。すなわち、入力を ASCII NUL で分離された項目として扱い、出力する各項目の末尾に ASCII NUL を付加する。このオプションは、perl -0, find -print0, xargs -0 などと組み合わせて使用すると、便利なことがある。そうしたコマンドでも、わがままなファイル名を (空白などの特殊文字を含んでいる場合でも) きちんと確実に処理するために、同様なことをしているのである。

例を挙げる。

     shuf <<EOF
     A man,
     a plan,
     a canal:
     Panama!
     EOF

上記の結果は、こんな出力になるかもしれない。

     Panama!
     A man,
     a canal:
     a plan,

同様に、次のコマンドの出力は、

     shuf -e clubs hearts diamonds spades

こうなるかもしれない。

     clubs
     diamonds
     spades
     hearts

下記は、shuf -i 1-4 というコマンドの出力の一例である。

     4
     2
     1
     3

上記のどの例でも、入力行は 4 行である。従って、入力は 24 とおりに並べ替えることが可能であり、shuf が生成するのは、そのどれか一つである。一般的に言うと、入力行が N 行なら、N! とおりに (N の階乗、すなわち、N * (N - 1) * ... * 1 とおりに) 並べ替えて、出力することができる。

それぞれが 0 から 9 までの範囲にある数値を 50 回ランダムに出力するには、次のようにする。

     shuf -r -n 50 -i 0-9

コイン・トス 100 回をシミュレートする。

     shuf -r -n 100 -e Head Tail

終了ステータス 0 は成功を示し、0 以外の値は失敗を示す。

uniq: ファイルから重複を省く
=================

uniq は、指定された INPUT ファイルにある行を、重複を省いて書き出す。ファイルが指定されていない場合や、INPUT として - が指定されている場合は、標準入力を対象とする。

書式:

     uniq [OPTION]... [INPUT [OUTPUT]]

デフォルトでは、uniq は入力された行を表示するとき、隣接する同一行があれば、出力に重複する行が現れないように、最初の行だけを残して、残りの行を捨ててしまう。また、オプションによっては、重複しない行を捨てることや、すべての隣接する同一行を捨てることもできる。

入力はソートされている必要はないが、重複する入力行が検出されるのは、それが隣接しているときだけである。もし、隣接していない重複行も捨てたいのなら、 sort -u を使うとよいだろう。 See sort invocation.

比較には LC_COLLATE ロケール・カテゴリが指定しているルールを使用する。

OUTPUT ファイルが指定されていない場合、uniq は標準出力に書き出す。

このプログラムでは以下のオプションが使用できる。参照: Common options.

-f N
--skip-fields=N
     重複の検査を行う前に、各行のフィールドを N 個スキップする。その行に N 個より少ないフィールドしかない場合は、比較に空の文字列を使用する。フィールドとは、少なくとも 1 個以上のスペースやタブで間を区切られた、スペースやタブを含まない文字の連続である。

     互換性のために、uniq は -N という旧来のオプション書式をサポートしている。新しいスクリプトでは、-f N の方を使うべきである。

-s N
--skip-chars=N
     重複の検査を行う前に、N 文字スキップする。その行に N 個より少ない文字しかない場合は、比較に空の文字列を使用する。フィールドをスキップするオプションと、文字をスキップするオプションの両方を使っている場合は、フィールドのスキップが先に行われる。

     POSIX 1003.1-2001 に準拠していないシステムでは、uniq が +N という旧来のオプションの書式をサポートしている。この旧来の書式は、環境変数 _POSIX2_VERSION を使えば、コントロールできるが (see Standards conformance)、移植を考慮したスクリプトでは、この環境変数に動作が依存するコマンドの使用は、避けた方がよい。たとえば、uniq +10 ではなく、uniq ./+10 や uniq -s 10 を使うべきだ。前者では、+10 が、オプションかファイル名か、まぎらわしいからである。

-c
--count
     各行に出現回数を付けて表示する。

-i
--ignore-case
     行を比較するとき、アルファベットの大文字小文字を区別しない。

-d
--repeated
     重複していない行を除去する。このオプションを単独で使った場合、uniq は、連続する同一行のうち、最初の 1 行だけを表示し、それ以外の何も表示しない。

-D
--all-repeated[=DELIMIT-METHOD]
     入力行のうち、連続する同一行の二行目以降を除去せず、重複していない行だけを除去する。このオプションが役に立つのは、主として、大文字小文字を無視するとか、選択したフィールドのみを比較するとかいった、他のオプションと組み合わせて使うときである。長い書式のオプションで使用できる DELIMIT-METHOD は、省略可能であり、指定した場合は、重複行のグループ間の区切り方を指示することになる。 DELIMIT-METHOD は、以下の一つでなければならない。

     none
          重複行のグループ間に、区切りの印を置かない。--all-repeated (-D) とのみ指定するのと同じことである。

     prepend
          重複行の各グループの前に改行を出力する。
          --zero-terminated (-z) を指定している場合は、
          区切りの印として改行の代わりに、ゼロバイト (ASCII NUL) を使用する。

     separate
          重複行のグループ間を 1 個の改行で分離する。これは、prepend を使うのとほぼ同じだが、最初のグループの前に区切りの印を挿入しないのが異なっている。それ故、ユーザが出力を直接見る場合に、より適しているかもしれない。--zero-terminated (-z) を指定している場合は、
          区切りの印として改行の代わりに、ゼロバイト (ASCII NUL) を使用する。

     注意していただきたいが、グループ同士を改行で分離しているとき、
     入力ストリームに複数の空行があると、出力がまぎらわしいものになる。
     これを避けるには、入力を tr -s '\n' でフィルタリングして、
     複数の空行をなくせばよい。

     このオプションは、GNU による拡張である。

--group[=DELIMIT-METHOD]
     すべての行を出力し、他と区別される各グループの間に区切りを入れる。 --zero-terminated (-z) を指定している場合は、
     区切りの印として改行の代わりに、ゼロバイト (ASCII NUL) を使用する。 DELIMIT-METHOD は省略可能であり、指定した場合は、グループ間の区切り方を指示することになる。 DELIMIT-METHOD は、以下の一つでなければならない。

     separate
          他と区別されるグループを 1 個の区切りの印で分離する。これが、何も指定されていないときの、デフォルトの区切り方であり、出力をユーザに直接見せる場合に適している。

     prepend
          他と区別される各グループの前に区切りの印を出力する。

     append
          他と区別される各グループの後ろに区切りの印を出力する。

     both
          他と区別される各グループの前後に区切りの印を出力する。

     注意していただきたいが、グループ同士を改行で分離しているとき、
     入力ストリームに複数の空行があると、出力がまぎらわしいものになる。
     これを避けるには、入力を tr -s '\n' でフィルタリングして、
     複数の空行をなくせばよい。

     このオプションは、GNU による拡張である。

-u
--unique
     重複する入力行のグループを表示するときは (訳注: すなわち、--all-repeated (-D) オプションを使用しているときは)、グループの最後の行を表示しない。このオプションを単独で使用する場合は、ユニークな (訳注: この場合は、同一行が連続していないという意味) 行だけを表示し、それ以外の何も表示しない。

-w N
--check-chars=N
     各行で (フィールドや文字をスキップする指定があれば、スキップした後で) 文字を何個まで比較するかを指定する。デフォルトでは、行の残り全部が比較の対象になる。

     -z オプションを使用した場合、改行文字はフィールド・セパレータ扱いになる。

終了ステータス 0 は成功を示し、0 以外の値は失敗を示す。

comm: ソート済みの二つのファイルを一行づつ比較する
============================

comm は、二つの入力ファイルの共通する行と独自な行を、標準出力に区別して書き出す。 - というファイル名は、標準入力を意味している。

書式:

     comm [OPTION]... FILE1 FILE2

入力ファイルは、comm に渡す前に、LC_COLLATE のロケールによって規定されている照合順序でソートされていなければならない。入力ファイルが改行以外の文字で終わっている場合は、自動的に改行が追加される。 sort コマンドをオプションなしで実行すると、comm の入力にふさわしいファイルが必ず得られる。

オプションを付けずに実行すると、comm は 3 列の出力を生成する。 1 列目は FILE1 にのみある行であり、2 列目は FILE2 にのみある行、そして 3 列目は両方のファイルに共通する行である。各列は、1 個のタブ文字で区切られる。

-1, -2, -3 というオプションは、対応する列 (と区切り記号) を表示しないようにする。オプションについては、「共通オプション」の章も参照すること。 Common options.

比較のための他のユーティリティとは違って、comm の終了ステータスは、比較結果の如何によらない。comm は、正常終了すると 0 の終了コードを返す。エラーがあれば、0 以外のステータスで終了する。

--check-order を指定した場合、入力がソートされていないと、エラーメッセージを出して、実行を中断する。--nocheck-order オプションを指定した場合は、入力がソートされていなくても、エラーメッセージを出すことはない。どちらのオプションも指定されていない場合に、入力がソートされていないとの診断を下すのは、片方の入力ファイルにもう一方と対にならない行が見つかったときだけである。入力ファイルがソートされていないと診断すると、comm は 0 以外のステータスで終了する (従って、そうした出力は使用するべきではない)。

入力ファイルがきちんとソートされていず、しかも、対にならない行を含む場合に、 --nocheck-order を指定して、そうしたファイルを comm で無理矢理処理しても、何か特定の結果をもたらすことは保証できない。おそらく出力は、期待に添わないものになるだろう。

--check-order
     入力ファイルのどちらかの内容がきちんとソートされていないと、エラーメッセージを出して、実行に失敗する。

--nocheck-order
     入力ファイルの内容がソートされた順番になっているかどうかを、どちらのファイルについてもチェックしない。

     その他のオプション。

--output-delimiter=STR
     出力における隣り合う列の間に、デフォルトのタブ文字 1 個ではなく、 STR を出力する。

     区切り記号の STR は、空であってはならない。

--total
     最後の行に要約を出力する。

     通常の出力と同じように、1 列目は FILE1 にのみある行の合計数、 2 列目は FILE2 にのみある行の合計数、3 列目は両方のファイルに共通する行の合計数である。さらに 4 列目に total という文字が追加される。

     次の例では、comm は通常の出力を省略して (-123)、要約のみを表示している。

          $ printf '%s\n' a b c d e     > file1
          $ printf '%s\n'   b c d e f g > file2
          $ comm --total -123 file1 file2
          1       2       4       total

     このオプションは GNU の拡張である (coreutils 8.26 から)。移植を考慮したスクリプトで合計数を出したければ、wc を使用するべきである。たとえば、上記の例なら、次のようにする。

          $ comm -23 file1 file2 | wc -l    # file1 にのみある行の行数
          1
          $ comm -13 file1 file2 | wc -l    # file2 にのみある行の行数
          2
          $ comm -12 file1 file2 | wc -l    # 両方のファイルに共通する行の行数
          4

-z
--zero-terminated
     項目の区切りに、改行 (ASCII LF) ではなく、ゼロバイトを使用する。すなわち、入力を ASCII NUL で分離された項目として扱い、出力する各項目の末尾に ASCII NUL を付加する。このオプションは、perl -0, find -print0, xargs -0 などと組み合わせて使用すると、便利なことがある。そうしたコマンドでも、わがままなファイル名を (空白などの特殊文字を含んでいる場合でも) きちんと確実に処理するために、同様なことをしているのである。

ptx: パミューテド・インデックスを作成する
=======================

ptx の基本的な働きは、テキストファイルを読み込んで、パミューテド・インデックスを作成することである。パミューテド・インデックスというのは、各キーワードに前後の文脈を付けて索引項目にするインデックスのことだ。

(訳注: パミューテド・インデックスは、KWIC (Key Word In Context) インデックスとも言われる。簡単に言えば、本文にあるとおり、キーワードに前後の文脈を付けて項目として立てる索引のことである。たとえば、"The cow jumped over the moon." という文があるとしよう。今、キーワードを角カッコ ([]) で示すとすると、ptx による一番簡単なパミューテド・インデックスの作成では、この文から、

     [The] cow jumped over the moon.
     The [cow] jumped over the moon.
     The cow [jumped] over the moon.
     The cow jumped [over] the moon.
     The cow jumped over [the] moon.
     The cow jumped over the [moon].

という、キーワードの位置だけが違う 6 個の索引項目が作られ、キーワードによってソートされて、出力される。「パミューテド (permuted)」というのは、文中でキーワードが順番に移動するのを、円順列 (cyclic permutation) に見立てているかららしい。「順列索引」と訳されることもある。

上記の文を cow.txt というファイルに保存し、それに対して -A オプションのみを付けて ptx を実行してみよう。その出力は、次のようになる。出力された行のほぼ中央にある (すなわち、少し長めの空白の後ろの) 単語がキーワードである。大文字小文字を区別してアルファベット順に並んでいるのが、おわかりになるだろう。各行頭にあるのは、-A オプションによって生成された参照箇所情報 (ファイル名と行番号) である。

     $ echo "The cow jumped over the moon." >cow.txt
     $ ptx -A cow.txt
     cow.txt:1:  .                        The cow jumped over the moon
     cow.txt:1:                     The   cow jumped over the moon.
     cow.txt:1:                 The cow   jumped over the moon.
     cow.txt:1: The cow jumped over the   moon.
     cow.txt:1:          The cow jumped   over the moon.
     cow.txt:1:     The cow jumped over   the moon.

パミューテド・インデックスの代表的な例としては、英語などの聖書の巻末に付属している文脈付きの語句索引、「コンコーダンス」を挙げることができる。実際、この文書でもコンコーダンスをパミューテド・インデックスの同義語として使用している。なお、この ptx プログラムは、日本語に対応していない。)

ptx 実行の書式は次のうちのどちらかである。

     ptx [OPTION ...] [FILE ...]
     ptx -G [OPTION ...] [INPUT [OUTPUT]]

-G (または、それと等価な --traditional) オプションを指定すると、 GNU によるすべての拡張が無効になり、従来のモードで動作するようになる。従って、いくつかの制限が課されるようになり、プログラムのオプションのデフォルトの値がいくつか変更される。 -G が指定されていない場合は、GNU による拡張が常に有効になる。 ptx に対する GNU の拡張については、この文書では折に触れて説明している。拡張の詳細なリストについては、「GNU による ptx の拡張」の節を御覧になっていただきたい。 See Compatibility in ptx.

個々のオプションについては、以下に続く節で説明する。

GNU による拡張が有効になっていれば、オプションの後ろに 0 個以上の FILE を指定することができる。FILE を一つも指定しない場合は、標準入力が読み込まれる。 FILE を 1 個以上指定した場合、それは入力ファイルの名前であり、入力ファイルはすべて順番に、あたかもすべてのファイルが結合されているかのように読み込まれる。とは言え、各ファイル同士は文脈的に完全に分離しており、参照箇所情報の自動作成を指定している場合に、参照箇所のファイル名や行番号が指し示すのは、個々の入力テキストファイルのそれである。どの場合でも、ptx は、パミューテド・インデックスを標準出力に出力する。

GNU による拡張が有効になっていない場合、すなわち、プログラムが従来モードで動作する場合は、オプションのほかに 0 から 2 個のパラメータを指定できる。パラメータがない場合、プログラムは標準入力を読み込んで、標準出力にパミューテド・インデックスを出力する。パラメータが 1 個だけの場合、それが示しているのは、標準入力の代わりに読み込まれるテキストファイル (訳注: 上記書式の INPUT) の名前である。パラメータが二つある場合、それぞれが示しているのは、読み込み対象の INPUT ファイルと出力先の OUTPUT ファイルの名前だ。この場合、二番目のパラメータによって指定されたファイルの元の内容が破壊されることに、くれぐれも気をつけていただきたい。この動作は、System V の ptx との互換性を維持するために必要になっているものだが、通常 GNU の規格では、オプションによって指定されるのではない出力パラメータを、使用しないように勧めている。

オプションの値や入力テキストファイルとして指定するいかなるファイルに対しても、ファイル名の代わりに 1 個のダッシュ - を使用することができる。その場合は、標準入力が使われることになる。もっとも、この習慣をプログラム 1 回の起動につき 1 回以上使うのは、たぶん理屈に合わない。

一般オプション
-------

-G
--traditional
     すでに述べたように、このオプションは ptx に対する GNU による拡張のすべてを無効にして、動作を従来モードに切り替える。

--help
     簡単なヘルプメッセージを標準出力に表示し、それ以上の処理をせずに終了する。

--version
     プログラムのバージョンを標準出力に表示し、それ以上の処理をせずに終了する。

終了ステータス 0 は成功を示し、0 以外の値は失敗を示す。

ptx が使用する文字セット
--------------

現在の設定では、ptx プログラムは、入力ファイルが符号化に 8-bit の ISO 8859-1 コード (Latin-1 文字セットとも言われる) を使用していると見なすようになっている。ただし、MS-DOS 用にコンパイルされている場合は別で、その場合は、IBM-PC の文字セットが使用される (GNU の ptx が MS-DOS マシンで使えるかどうか、今ではわからないけれど)。 7-bit ASCII と比べると、ISO 8859-1 の文字セットは、アルファベットの部分が異なっている。そのため、正規表現におけるマッチングの振る舞いが変わってくる。キーワードに対するデフォルトの正規表現が (訳注: つまり、GNU の拡張が有効なときの \w+ が)、英語で使用しない文字や、ウムラウトやアクセントのような発音区別符の付いた文字を受け入れることになるのである。とは言え、キーワードのソート方法は今だに大雑把であり、使用している文字セットの順序にきわめて盲目的に従っている。

-f
--ignore-case
     ソートするとき、小文字を大文字と同じものとして扱う。

単語の選択と入力の処理
-----------

-b FILE
--break-file=FILE

     このオプションを使えば、単語を構成するのはどんな文字かを、-W とは別のやり方で定義することができる。このオプションでファイルを指名し、そこに、単語の構成要素になることができない文字のリストを入れておくのである。このファイルは、Break file と呼ばれる。Break file に含まれていないいかなる文字も、単語の構成要素になるわけだ。-b と -W の両方のオプションが指定されている場合は、-W の方が優先され、-b は無視される。

     GNU の拡張が有効になっているとき、改行を単語区切り文字 (break character) にしない唯一の方法は、単語区切り文字をすべて Break file に書き込み、そこに改行を全く含めないことである。Break file 末尾の改行も除かなければならない。 GNU の拡張が無効な場合、スペース、タブ、改行は、それが Break file に含まれていなくても、常に単語区切り文字と見なされる。

-i FILE
--ignore-file=FILE

     このオプションで指名するファイルには、出力するコンコーダンスでキーワードとして採用しない単語のリストを入れておく。このファイルは、Ignore file と呼ばれる。このファイルは、1 行 1 単語の形式であり、単語の分離は常に行末によって行われて、 -S オプションの値の影響を受けることはない。

-o FILE
--only-file=FILE

     このオプションで指名するファイルには、出力するコンコーダンスでキーワードとして採用する単語のリストを入れておく。このファイルに書かれていないどんな単語も、キーワードとして採用されることはない。このファイルは、Only file と呼ばれる。このファイルは、1 行 1 単語の形式であり、単語の分離は常に行末によって行われて、 -S オプションの値の影響を受けることはない。

     Only file として使われるデフォルトのファイルは存在しない。Only file と Ignore file の両方が指定されている場合に、ある単語がキーワードと見なされるのは、その単語が Only file に存在し、しかも Ignore file に存在しないときだけである。

-r
--references

     各入力行において、行頭にあるホワイトスペース以外の文字の連続を参照箇所情報 (訳注: たとえば、ファイル名、ページ番号、行番号など) として扱うようにする。この参照箇所情報は、その入力行がどこにあるかを、作成されるパミューテド・インデックス中で示すために用いられる。参照箇所情報の生成についての詳細は、次節「出力のフォーマット」を御覧いただきたい。 See Output formatting in ptx. このオプションを使用すると、-S オプションのデフォルトの値が変更されることになる (訳注: すなわち、GNU の拡張が有効な場合も、-S オプションのデフォルト値が文末ではなく、行末になる)。

     このオプションを使用したとき、ptx プログラムは、参照箇所情報が出力される文脈に混入しないようにするが、その試みはそれほど徹底したものではない。しかし、文脈が改行できちんと終止していれば、 ptx はその試みに成功する。もし、-r オプションが -S オプションのデフォルト値とともに使われているか、あるいは、GNU の拡張が無効になっているならば、この条件は必ず満たされることになる。従って、その場合は、参照箇所情報が出力される文脈からきちんと分離される。

     (訳注: 文脈 (context) というのは、出力については、キーワードとその前後と考えておけばよいが、入力について言うと、 ptx が操作の対象にする本文の単位 --- 入力のまとまり --- を指すことになる。 -S の値によって、普通は文か、行になる。)

-S REGEXP
--sentence-regexp=REGEXP

     このオプションでは、行の終わり、または文の終わりを示す正規表現を指定する。

     (訳注: もう少し説明すると、このオプションで指定するのは、入力を何で区切るかということである。改行で区切れば、いわゆる行が、ptx の操作の対象となる入力のまとまり (入力の単位) になり、ピリオドなどで区切れば、いわゆる文が、入力のまとまりになる。このまとまりが ptx にとっての文脈でもある。ただし、出力では、文脈のすべてが表示されるとはかぎらない。なお、そうしたければ、行末や文末以外で入力を区切ることもできる。)

     実際のテキストでは、ここで指定される正規表現のみが、行の終わりや文の終わりの指標として使われているとはかぎらない。また、入力の区切りに何を指定しようとも、このオプションの外で特別な意味を持つことはない (訳注: すなわち、オプション -A, -i, -o などには影響が及ばない)。デフォルトでは、GNU の拡張が有効なとき、-r オプションが指定されていなければ、文の終わりの方が入力の区切りとして使われる。その場合は、GNU Emacs から取り込まれた次の正規表現が使用される。

          [.?!][]\"')}]*\\($\\|\t\\|  \\)[ \t\n]*

     GNU の拡張が無効になっている場合や、-r オプションが指定されている場合は、行の終わりの方が入力の区切りとして使用される。その場合、デフォルトの正規表現は、単に次のものである。

          \n

     空の REGEXP を使用するのは、行末や文末の認識を全く無効にするのと同じである。その場合、ファイル全体が、たった 1 個の長い行、あるいは、長い文と見なされることになる。ユーザとしては、オプション -F "" を使用して、省略の印の生成も全く行わないようにしたくなるかもしれない。 See Syntax of Regular Expressions (The GNU Emacs Manual).

     キーワードがたまたま入力行や入力文の先頭近くにあると、出力する文脈行の行頭に、使用しない領域が生ずることがよくある。また、キーワードが入力行や入力文の末尾近くにあると、出力する文脈行の行末に、使用しない領域がしばしば生ずる。 ptx プログラムは、その文脈を折り返して、そうした不使用領域を埋めようと試みる。すなわち、その入力行や入力文の後続する部分 (TAIL) を使って、出力する行の左にある不使用領域を埋め、その入力行や入力文の先行する部分 (HEAD) を使って、出力する行の右にある不使用領域を埋めるのである。

     このオプションの引数中では、ユーザーの便宜のために、 C 言語由来のよく使うバックスラッシュ・エスケープシーケンスの多くが、ptx そのものによって認識され、対応する文字に変換されるようになっている。

-W REGEXP
--word-regexp=REGEXP

     このオプションでは、各キーワードとなる単語とはどのようなものかを示す正規表現を指定する。デフォルトでは、GNU の拡張が有効になっていれば、単語とはアルファベットの文字の連続である。すなわち、使用される正規表現は \w+ だ。 GNU の拡張が無効な場合、デフォルトで単語と見なされるのは、何であれ、スペース、タブ、改行で区切られているものである。この場合、使用される正規表現は [^ \t\n]+ になる。

     REGEXP に空の文字列を指定するのは、このオプションを使用しないのと同じことである。 See Syntax of Regular Expressions (The GNU Emacs Manual).

     このオプションの引数中では、ユーザーの便宜のために、 C 言語で見られるような、よく使うバックスラッシュ・エスケープシーケンスの多くが、 ptx そのものによって認識され、対応する文字に変換されるようになっている。

出力のフォーマット
---------

出力のフォーマットを決めるのは、主として -O と -T オプションだが、両者については、以下のオプション一覧で説明している。-O も -T も指定されず、しかも、GNU の拡張が有効な場合、ptx プログラムは、ダム端末に適した出力フォーマットを選択する。各キーワードは一行の中央に表示され、前後の文脈がその左右に出力される。コンコーダンスとしての出力が一目でわかるように (訳注: すなわち、どれがキーワードで、どれがその前後の語句かわかりやすいように)、各フィールドはきちんと揃えられる。おまけの機能として、次のものがある。参照箇所情報の自動作成が -A オプションによって選択され、参照箇所が左側の文脈の前に表示される場合には (すなわち、-R オプションが選択されていない場合には)、参照箇所の後ろにコロンが追加される。こうしておくと、参照箇所を GNU Emacs の next-error 処理にうまく渡せるようになるのである。このデフォルトの出力フォーマットでは、改行やタブのようなホワイトスペース文字は、それぞれ単にただ 1 個のスペースに変換されるだけであり、連続するスペースをわざわざ圧縮するようなことは行われない。この動作は、将来変更されるかもしれない。そうしたホワイトスペース文字を除いて、使用している 256 文字からなる文字セット中のほかのすべての文字は、入力から出力へと手を加えずにそのまま送り出される。

出力フォーマットは、以下のオプションによって、さらに制御される。

-g NUMBER
--gap-size=NUMBER

     出力行の各フィールドは、ホワイトスペースによって区切られるが、そのフィールド同士の間隔の最小サイズを指定する。

-w NUMBER
--width=NUMBER

     最終的に出力される各行の最大長を指定する。参照箇所を使用する際、その長さが最大長に含まれるかどうかは、 -R オプションを付けるか付けないかよって決まる。 -R オプションを指定しない場合、すなわち、参照箇所が左の文脈より前に表示される場合は、すべての参照箇所中の最大長が、出力行の最大長の長さの内に含まれることになる。-R オプションを指定した場合、すなわち、参照箇所が右の文脈より後に表示される場合は、参照箇所や、それに先行するフィールドの区切りが占める領域は、出力行の最大長の長さに含まれない。

-A
--auto-reference

     参照箇所情報の自動生成を選択する。ファイル名と行番号からなる参照箇所が自動的に生成されて、各入力行に付くことになる。ファイル名と行番号は 1 個のコロンで区切られる。ただし、標準入力から読み込んでいる場合は、ファイル名は空になる。 -A と -r の両方のオプションが指定されている場合は、入力中にある参照箇所情報が読み込まれた上で本文から外されることは -r 単独の場合と同じだが、出力時に使用されるのは、自動生成された参照箇所の方である。すなわち、入力中にある参照箇所情報は、自動生成されたもので置き換えられる。

-R
--right-side-refs

     デフォルトの出力フォーマットでは、-R オプションを使用しない場合、 -r や -A オプションの働きによって生成される参照箇所は、出力行の左の端、すなわち、左の文脈の前に表示される。それに対して、デフォルトの出力フォーマットで -R オプションを指定した場合、参照箇所が表示されるのは、各出力行の右端、すなわち、右の文脈の後ろになる。ほかのいかなる出力フォーマットにおいても、基本的に -R オプションは無視されるが (訳注: デフォルト以外の出力フォーマットでは、 -R オプションがあってもなくても、参照箇所は右端に出力される)、それでも、-R オプションが付いていると、参照箇所の長さが、-w で指定した出力行全体の長さの内に入らないという働きだけは残る。

     このオプションは、GNU の拡張が無効であるときは、常に自動的に選択される。

-F STRING
--flag-truncation=STRING

     このオプションを指定すると、出力に省略があった場合、それを示すために文字列 STRING を使用するようになる。ほとんどの出力フィールドは、理論上では、-S オプションで何を選択するかによって、現在の行、または、現在の文の、先頭や末尾に向かって伸びて行くものである。しかし、-w オプションによって長さを変更できるとは言え、出力行には許される最大長というものがあり、その最大長はさらにさまざまな出力フィールドで使用する領域に分割されている。従って、フィールドは、それを収納する現在の出力行の先頭や末尾を越えて伸ばすことができないために、切り詰めなければならないことがあり、そういうときに、省略が行われるのである。省略の指標として使用されるデフォルトの文字列は、1 個のスラッシュである。これは、-F / と指定した場合と同じだ。

     STRING には、-F ... のように 1 個以上の文字を指定してもよい。また、STRING が空文字列 (-F "") の場合には、省略のフラグは立てられないことになり、従って、省略の指標は一切付加されない。

     このオプションの引数中では、ユーザーの便宜のために、 C 言語で見られるような、よく使うバックスラッシュ・エスケープシーケンスの多くが、 ptx そのものによって認識され、対応する文字に変換されるようになっている。

-M STRING
--macro-name=STRING

     nroff や troff、あるいは TeX で処理するのにふさわしい出力フォーマットを生成するとき、 xx の代わりに使用する別の文字列 STRING を指定する。 (訳注: -O や -T オプションを参照。)

-O
--format=roff

     出力フォーマットとして、nroff や troff で処理するのに適した形式を選択する。各出力行は次のようになる。 (訳注: 下記の TAIL と HEAD については、前節 --sentence-regexp オプションの説明の終わりから 2 番目のパラグラフをご覧いただきたい。 REF は参照箇所である。)

          .xx "TAIL" "BEFORE" "KEYWORD_AND_AFTER"
           "HEAD" "REF"

     従って、あとは、出力の整形を担当する roff のマクロ .xx を出力ファイルに書き込めばよいことになる。この出力フォーマットは、 GNU の拡張が無効なときのデフォルトである。xx を別のマクロ名に変更するには、 -M オプションを使用すればよい (訳注: -M "xx" のように、xx の部分のみ指定する)。

     この出力フォーマットでは、改行やタブのような非表示文字は、それぞれただ 1 個のスペースに変換されるだけで、連続するスペースをわざわざ圧縮するようなことは行われない。ダブルクォート文字 " はそれぞれ二重化されるので、 nroff や troff によって正しく処理される。

-T
--format=tex

     出力フォーマットとして、TeX で処理するのに適した形式を選択する。各出力行は、次のようになる。 (訳注: 下記の TAIL と HEAD については、前節 --sentence-regexp オプションの説明の終わりから 2 番目のパラグラフをご覧いただきたい。 REF は参照箇所である。)

          \xx {TAIL}{BEFORE}{KEYWORD}
          {AFTER}{HEAD}{REF}

     従って、あとは、出力の整形を担当する \xx コマンドの定義を出力ファイルに書き込めばよいことになる。なお、参照箇所の生成が行われていない場合、すなわち、-A オプションも -r オプションも指定されていない場合には、各 \xx 呼び出しの最後の引数は出力されないことに注意していただきたい。 xx を別のマクロ名に変更するには、-M オプションを使用すればよい (訳注: -M "xx" のように、xx の部分のみ指定する)。

     この出力フォーマットでは、$, %, &, #, _ のような特殊文字のいくつかは、自動的にバックスラッシュで保護される。波カッコ {, } は、一対のドル記号とバックスラッシュとで保護される (強引に数式モードにするわけだ)。バックスラッシュそのものは、\backslash{} というシーケンスになる。同形の他の文字と区別するために文字の上下に付ける発音区別符のうち、サーカムフレックスとチルダは、それぞれ \^{ } と \~{ } というシーケンスになる (訳注: 実際には { } の位置に a  なり e なりといった文字が来る)。使用している文字セット中の他の発音区別符が付いている文字についても、可能なかぎり、適切な TeX のシーケンスが生成される。それ以外の文字について言うと、改行やタブのような非表示文字や、ASCII の文字セットに属さない他のすべての文字は、単にただ 1 個のスペースに変換され、連続するスペースをわざわざ圧縮するようなことは行われない。 TeX のための特殊文字の処理は以上のようなものだが、改善する方法があれば、作者までお知らせいただきたい。

GNU による ptx の拡張
---------------

このバージョンの ptx には、System V の ptx には存在しない機能がいくつかある。そうした追加機能は、コマンドラインオプションの -G を使えば、働かなくなるが、ほかのコマンドラインオプションによって上書きされれば、話は別である。もっとも、GNU の拡張の中には、上書きによって回復できないものもあるので、 GNU の拡張を使いたければ、-G オプションを最初から使わないのが、すっきりした方法だ。以下に、このプログラムと System V の ptx の相違点を挙げておく。

  * このプログラムでは、一度に複数の入力ファイルを読み込むことができる。また、生成したコンコーダンスは、常に標準出力に書き出される。それに対して、System V の ptx は、ファイルをたった 1 個しか読み込まず、結果を書き出すのは、標準出力のこともあるが、コマンドに 2 番目の FILE パラメータが指定されていれば、その FILE に対してである。

     オプションで指定しない出力パラメータを持つのは、危険な習慣であり、 GNU では、できるだけ避けるようにしている。従って、ptx を GNU と System V のどちらでも、問題なく同じように使いたいなら、入力ファイルは常に一つしか使わず、実行結果は常に標準出力に書き出されるものと考えておいた方がよい。また、ptx を使用してアプリケーションを作成する場合には、インストールされている ptx で -G オプションが使用できるとわかれば、 ptx を呼び出すとき、-G オプションを必ず付けるようにしたくなるかもしれない。

  * System V の ptx で利用できるオプションは、-b, -f, -g, -i, -o, -r, -t, -w だけである。他のオプションは、すべて GNU の拡張だが、今この箇条書きで繰り返すことはしない。なお、オプションの中には、以下でも述べているように、GNU の拡張が有効になっていると、効果が少し変わるものもある。

  * GNU の拡張のデフォルトでは、コンコーダンス出力のフォーマットは、 troff や nroff 向けになっていない。むしろ、ダム端末向けのフォーマットになっている。troff や nroff 向けの出力を選択したかったら、-O オプションを使用すればよい。

  * -R オプションを使用しないと、参照箇所の最大長が、出力行全体の長さから差し引かれる。 GNU の拡張を無効にすると、参照箇所の長さは、出力行の長さの勘定に入らないことになる。

  * GNU の拡張が無効になっていても、256 バイトの文字セットのすべての文字が --- ASCII NUL バイト含めて --- 常に入力ファイルから読み込まれて処理され、有害な作用をもたらすことはない。それに対して、 System V の ptx は、8-bit の文字を受け付けない。若干の制御文字も拒否する。また、チルダ ~ も拒否する。

  * GNU の拡張が無効になっていても、入力行の長さは、利用できるメモリによってしか制限されない。それに対して、System V の ptx が処理の対象にするのは、各行に付き最初の 200 文字だけである。

  * 単語区切り文字 (break character、単語を構成しない文字) のデフォルトは、使用している文字セットにおけるアルファベットのすべての文字 (発音区別符のあるなしを問わない) 以外のあらゆる文字である。 GNU の拡張が無効な場合は、単語区切り文字のデフォルトは、スペース、タブ、改行のみになる。

  * このプログラムは、出力行の長さを System V の ptx より上手に処理する。 GNU の拡張が無効になっている場合、このプログラムは System V の ptx の動作をなるべく真似ようとするが、それでも、System V のちょっとした癖のいくつかは、完全には再現できない。

  * ユーザは Ignore file と Only file の両方を指定することができる。 System V の ptx では、そんなことはできない。

tsort: トポロジカル・ソート
=================

tsort は、指定された FILE に対してトポロジカル・ソートを行う。入力ファイルが指定されていない場合や、FILE として - が指定されている場合は、標準入力を対象にする。より詳しい説明や、このコマンドが作成された経緯については、次節「tsort: 誕生の背景」を御覧になっていただきたい。 tsort background

書式:

     tsort [OPTION] [FILE]

tsort は入力を、空白で区切られた 2 個一組の文字列として読み込む。そうした文字列の各組は、部分的な順序を示している。出力は、与えられた部分的な順序に対応する全体としての順序である。

例を挙げよう。

     tsort <<EOF
     a b c
     d
     e f
     b c d e
     EOF

(訳注: 上の例は、"a b/c d/e f/b c/d e" という組を与えている。)

出力は、こうなる。

     a
     b
     c
     d
     e
     f

もっと現実的な例を考えてみよう。たくさんの関数をすべて一つのファイルに書いているとしよう。しかも、一つを除いて、他のすべての関数を static として宣言している。現在のところ、その例外 (main ということにする) が、ファイル中で定義されている最初の関数であり、それが直接呼び出す関数群がそれに続き、さらにその後に、その関数群が呼び出す関数が続く ... という形になっている。さて、ここで、プロトタイプを利用することにしたとしよう。そうなると、呼び出される関数のすべてを宣言するか (そのためには、定義の部分から情報をどっさりコピーしなければならない）、あるいは、できるだけ多くの関数が、使用される前に定義されているように、関数群を並べ替えるか、どちらかを選ばなければならない。後者の作業を自動化する方法の一つが、各関数についてそれが直接呼び出す関数のリストを作成することである。そうしたリストを生成するプログラムはたくさんある。いわゆるコール・グラフを作成するプログラムだ。以下のリストをご覧になっていただきたい。各行は、左側の関数が右側の関数を直接呼び出していることを示している。

     main parse_options
     main tail_file
     main tail_forever
     tail_file pretty_name
     tail_file write_header
     tail_file tail
     tail_forever recheck
     tail_forever pretty_name
     tail_forever write_header
     tail_forever dump_remainder
     tail tail_lines
     tail tail_bytes
     tail_lines start_lines
     tail_lines dump_remainder
     tail_lines file_lines
     tail_lines pipe_lines
     tail_bytes xlseek
     tail_bytes start_bytes
     tail_bytes dump_remainder
     tail_bytes pipe_bytes
     file_lines dump_remainder
     recheck pretty_name

ここで tsort を使用すると、こうした関数について、上記の後者の要求を満たすような順番を作成することができる。

     example$ tsort call-graph | tac
     dump_remainder
     start_lines
     file_lines
     pipe_lines
     xlseek
     start_bytes
     pipe_bytes
     tail_lines
     tail_bytes
     pretty_name
     write_header
     tail
     recheck
     parse_options
     tail_file
     tail_forever
     main

tsort は、入力にループがあれば検出し、出会った最初のループを標準エラーに書き出す。

一般に、ある部分的な順序に対して、唯一の全体的な順序というものは存在しないことに、留意していただきたい。上記のコール・グラフの場合で言えば、関数 parse_options は、main の前でありさえすれば、リストのどこにでも来ることができる。

オプションは、--help と --version だけである。 See Common options.

終了ステータス 0 は成功を示し、0 以外の値は失敗を示す。

tsort: 誕生の背景
------------

tsort が存在しているのは、Unix のリンカのごく初期のバージョンでは、一つのアーカイブファイルの処理をたった一回しか行わず、それも、ファイルの最初から最後へと順番に見ていくだけだったからである。当時の ld は、アーカイブ中の各オブジェクトを読み込むとき、そのオブジェクトがプログラムに必要かどうかの判断を、リンク作業のその時点でまだ定義されていない何らかのシンボルを定義しているかどうかを基準にして行っていた。

そのため、アーカイブ中の依存関係には、特別な扱いが必要になった。たとえば、scanf はたぶん read を呼んでいる。それは、リンカがアーカイブをたった一回最初から順番に読んで行くとき、scanf.o が read.o より前にあることが重要だったということである。なぜなら、そうなっていないと、scanf を呼ぶけれど、read を呼ばないプログラムでは、read に対する参照が、予期に反して "unresolved" になってしまいかねなかったからだ。

この問題に対処する方法は、次のようなものだった。まず、オブジェクトファイル同士の依存関係の集合を生成した。この作業は、lorder というシェルスクリプトによって行われていた。筆者の知るかぎり、現在 GNU では lorder というツールを提供していないが、 BSD 系のディストリビューションでは、今でもなお見つけることができる。

次に、この　lorder の出力に対して tsort を実行した。そして、そのソートされた結果を使って、アーカイブにオブジェクトを追加する順番を決めたのである。

こうした作業全体が、1980 年ごろから時代遅れのものになった。というのは、Unix のアーカイブは現在ではシンボル・テーブルを内蔵しており (従来は ranlib によって作られていたが、今ではたいてい ar そのものによって作られている)、Unix のリンカはこのシンボル・テーブルを使用して、アーカイブファイルに対する複数回の読み込みを効率的に行うからである。

ともあれ、これが tsort が誕生した経緯である。すなわち、当時のリンカのアーカイブファイルを取り扱う方法に問題があり、その問題を解決するための工夫だったのだ。そして、その問題は、その後、別のやり方で解決されるようになったのである。

フィールド操作
*******

cut: 各行の選択した部分を表示する
===================

cut は、各ファイルから各行の一部を抜き出して、標準出力に書き出す。ファイルが指定されていない場合や、ファイル名として - が指定されている場合は、標準入力を対象とする。

書式:

     cut OPTION... [FILE]...

以下のオプション一覧で BYTE-LIST, CHARACTER-LIST, FIELD-LIST と表記されているものは、コンマで区切られた、1 個以上の数字や範囲からなるリストである (範囲は、ダッシュを間に挟む 2 個の数字)。バイト、文字、フィールドは 1 から数える。不完全な範囲を指定することもでき、-M は 1-M と同じことであり、N- は N から行末、あるいは最後のフィールドまでと同じことである。リストの要素は、繰り返してもよく、部分的に重なり合ってもよく、どんな順序で指定してもよい。ただし、入力中の選択した部分が書き出されるのは、読み込まれたときと同じ順序であり、しかも、ただ一度だけである。(訳注: たとえば、-f 3,1,3 などと指定することはできるが、出力されるときは field-1, field-3 の順番であり、field-3 が二度出力されることもない。)

このプログラムでは以下のオプションが使用できる。参照: Common options.

-b BYTE-LIST
--bytes=BYTE-LIST
     BYTE-LIST で指定された位置にあるバイトのみを選択して、表示する。タブやバックスペースも他の文字と同様に扱う。すなわち、そうしたものも 1 バイトを占める。出力用のデリミタ (delimiter、区切りの印) が指定されている場合は (--output-delimiter の説明を参照)、選択されたバイトからなる範囲同士の間にデリミタ文字列を出力する。

-c CHARACTER-LIST
--characters=CHARACTER-LIST
     CHARACTER-LIST で指定された位置にある文字のみを選択して、表示する。現在のところ、-b と同じだが、プログラムの国際化が進むと、動作が変わることになるだろう。タブやバックスペースも他の文字と同様に扱う。すなわち、そうしたものも 1 文字と数える。出力用のデリミタが指定されている場合は (--output-delimiter の説明を参照)、選択された文字からなる範囲同士の間にデリミタ文字列を出力する。

-f FIELD-LIST
--fields=FIELD-LIST
     FIELD-LIST で指定されたフィールドのみを選択して、表示する。フィールドの区切りは、デフォルトではタブ文字 1 個である。なお、--only-delimited (-s) オプションが指定されていない場合は、デリミタ文字を全く含まない行も表示する。

     一言言っておくと、awk を使えば、もっと洗練されたフィールド処理ができるようになる。たとえば、フィールドの順番を入れ替える、空白文字を入れて列が揃うようにしたフィールドを取り扱う、そういったことが可能になる。 awk ならデフォルトで、フィールドの区切りに空白文字の連続を使用し (そして、フィールドの前後から除去し)、さらに、行頭と行末の空白を無視してくれるのだ。

          awk '{print $2}'      # 2 番目のフィールドを表示する
          awk '{print $(NF-1)}' # 最後から 2 番目のフィールドを表示する
          awk '{print $2,$1}'   # 最初の 2 フィールドを逆に並べる

     cut では、任意の順番でフィールドを指定することができるが、出力は常にファイル中で出会った順番であることに注意していただきたい。

     ありそうにないことだが、awk が利用できない状況だとしよう。その場合は、join コマンドを使えば、上記で awk がやっているように、空白文字を処理することができる。

          join -a1 -o 1.2     - /dev/null # 2 番目のフィールドを表示する
          join -a1 -o 1.2,1.1 - /dev/null # 最初の 2 フィールドを逆に並べる

-d INPUT_DELIM_BYTE
--delimiter=INPUT_DELIM_BYTE
     -f と併せて使うと、入力のフィールド区切りに INPUT_DELIM_BYTE の最初のバイトが使用される (デフォルトはタブ)。

-n
     マルチバイト文字を分割しない (現在のところ、機能しない)。

-s
--only-delimited
     -f を使うとき、フィールド区切り文字を含まない行の表示をしない。通常は、フィールド区切り文字を含まない行は、行全体がそのまま表示される。

--output-delimiter=OUTPUT_DELIM_STRING
     -f と一緒に使った場合は、出力フィールド間が OUTPUT_DELIM_STRING で区切られる。 -f を指定したときのデフォルトは、入力時のデリミタを使用することである。 -b や -c を使用して、(フィールドの範囲ではなく) バイト位置や文字位置の範囲を選択した場合は、選択されたバイトの重なり合わない範囲同士の間に OUTPUT_DELIM_STRING が出力される。

--complement
     このオプションは GNU の拡張である。-b, -c, -f オプションで選択されたバイト、文字、フィールドを含まない部分を選択して、表示する。言い換えれば、そうしたオプションによって指定されたバイトや文字やフィールドは「表示しない」ということだ。このオプションは、フィールドがたくさんあるとき、そのうちの一部を除いたすべてを表示したい場合に便利である。

-z
--zero-terminated
     項目の区切りに、改行 (ASCII LF) ではなく、ゼロバイトを使用する。すなわち、入力を ASCII NUL で分離された項目として扱い、出力する各項目の末尾に ASCII NUL を付加する。このオプションは、perl -0, find -print0, xargs -0 などと組み合わせて使用すると、便利なことがある。そうしたコマンドでも、わがままなファイル名を (空白などの特殊文字を含んでいる場合でも) きちんと確実に処理するために、同様なことをしているのである。

終了ステータス 0 は成功を示し、0 以外の値は失敗を示す。

paste: 複数のファイルの各行をマージする
=======================

paste は、指定された各ファイルの行番号が同じ行を、タブ文字を間にはさんで連結して、標準出力に書き出す。入力ファイルが全く指定されていない場合や、ファイル名が - だった場合は、標準入力が使用される。

書式:

     paste [OPTION]... [FILE]...

たとえば、次のような 2 個のファイルに対して、

     $ cat num2
     1
     2
     $ cat let3
     a
     b
     c

各ファイルから行を順番に拾う。

     $ paste num2 let3
     1       a
     2       b
             c

片方のファイルの行を二回使う。

     $ paste num2 let3 num2
     1       a      1
     2       b      2
             c

標準入力から行を取得して混ぜる。

     $ paste - let3 - < num2
     1       a      2
             b
             c

連続する行を、スペースを間にはさんで結合する。

     $ seq 4 | paste -d ' ' - -
     1 2
     3 4

このプログラムでは以下のオプションが使用できる。参照: Common options.

-s
--serial
     各ファイルから 1 行づつ取り出して連結するのではなく、一つのファイルのすべての行をまとめて 1 行に連結する。上の例のデータを使用すると、

          $ paste -s num2 let3
          1       2
          a       b       c

-d DELIM-LIST
--delimiters=DELIM-LIST
     連結する行の区切りに、タブではなく、DELIM-LIST の各文字を順番に使用する。 DELIM-LIST を使い切ってしまった場合は、最初の文字に戻って使用して行く。上記のデータを例に取ると、

          $ paste -d '%_' num2 let3 num2
          1%a_1
          2%b_2
          %c_

-z
--zero-terminated
     項目の区切りに、改行 (ASCII LF) ではなく、ゼロバイトを使用する。すなわち、入力を ASCII NUL で分離された項目として扱い、出力する各項目の末尾に ASCII NUL を付加する。このオプションは、perl -0, find -print0, xargs -0 などと組み合わせて使用すると、便利なことがある。そうしたコマンドでも、わがままなファイル名を (空白などの特殊文字を含んでいる場合でも) きちんと確実に処理するために、同様なことをしているのである。

終了ステータス 0 は成功を示し、0 以外の値は失敗を示す。

join: 共通のフィールドに基づいて行を結合する
=========================

join は、二つの入力ファイルを対象に、同一の共通フィールド (join field) を持つことで「対」になっている各行を、 1 行にまとめて、標準出力に書き出す。

書式:

     join [OPTION]... FILE1 FILE2

FILE1 と FILE2 の片方は -、すなわち標準入力であってもよい (両方とも標準入力は不可)。FILE1 と FILE2 は、共通フィールドに基づいてソートされているべきである。

通常、ソート順は、LC_COLLATE のロケールが規定している照合順序である。 -t オプションが指定されていない場合は、両ファイルについて並び方を比較する際、 sort -b の場合と同様に、共通フィールドの先頭にある空白が無視される。また、--ignore-case が指定されている場合は、 sort -f と同様、共通フィールドでアルファベットの大文字と小文字は区別されない。

sort の出力を join に渡すなら、sort と join が使用するロケールやオプションは首尾一貫していなければならない。 sort -k 1b,1 のようなコマンドを使用すれば、デフォルトの共通フィールドに基づいて、ファイルをソートすることができる。しかし、ロケール、共通フィールド、区切り記号、比較オプションなどにデフォルト以外のものを使用する場合は、 join と sort の間で矛盾が起きないように、そうしたものを選択しなければならないのだ。 join -t '' が指定された場合は、行全体が共通フィールドとして考慮の対象になるが、これは、sort のデフォルトの動作に対応している。

入力のすべての行が対になっている場合は、GNU による拡張が利用できる。この場合、並んでいる順番は、対になる二つのフィールドが同じであると判断されるならば、どんな順番でもよい。ただし、並び方の比較を上述のように行ったとき、二つのフィールドが同じだと判断される場合であり、その場合のみである。例を挙げよう。

     $ cat file1
     a a1
     c c1
     b b1
     $ cat file2
     a a2
     c c2
     b b2
     $ join file1 file2
     a a1 a2
     c c1 c2
     b b1 b2

--check-order を指定した場合、入力がソートされていないと、エラーメッセージを出して、実行を中断する。--nocheck-order オプションを指定した場合は、入力がソートされていなくても、エラーメッセージを出すことはない。どちらのオプションも指定されていない場合に、入力がソートされていないとの診断を下すのは、片方の入力ファイルにもう一方と対にならない行が見つかったときだけであり、それも入力ファイルのどちらも空ではなく、中身を持っているときだけである。入力ファイルがソートされていないと診断すると、join は 0 以外のステータスで終了する (従って、そうした出力は使用するべきではない)。

入力ファイルがきちんとソートされていず、しかも、対にならない行を含む場合に、 --nocheck-order を指定して、そうしたファイルを join で無理矢理処理しても、何か特定の結果をもたらすことは保証できない。おそらく出力は、期待に添わないものになるだろう。

デフォルトの動作は次のようになっている。

  * 共通フィールド (join field) は、各行の最初のフィールドである。

  * 入力の各フィールドは、1 個以上の空白 (スペースやタブ) で区切られる。行頭の空白は無視される。

  * 出力の各フィールドは、1 個のスペースで区切られる。

  * 各出力行の構成は、共通フィールド、FILE1 の残りのフィールド、 FILE2 の残りのフィールドの順になる。

このプログラムでは以下のオプションが使用できる。参照: Common options.

-a FILE-NUMBER
     FILE-NUMBER (1 か 2) のファイルに、もう一方のファイルと対にならない行がある場合、通常の出力のほかに、その行も表示する。

--check-order
     入力ファイルのどちらかの内容がきちんとソートされていないと、エラーメッセージを出して、実行に失敗する。

--nocheck-order
     入力ファイルの内容がソートされた順番になっているかどうかを、どちらのファイルについてもチェックしない。これが、デフォルトである。

-e STRING
     入力では欠けているフィールドを、出力では STRING で補う。すなわち、オプション -1, -2, -j, -o などを指定したときに、欠けているフィールドがそれに当たる。

--header
     各入力ファイルの最初の行をヘッダ行と見なす。ヘッダ行も結合され、最初の出力行として表示される。-o を使って、出力フォーマットを指定している場合は、ヘッダ行もそのフォーマットに従って出力される。ヘッダ行は、--check-order が指定されていても、並び順のチェックを受けない。なお、両ファイルのヘッダ行がマッチしない場合は、一番目のファイルのヘッダ・フィールドが使用される。

-i
--ignore-case
     キーを比較する際、アルファベットの大文字小文字を区別しない。このオプションを使用するときは、両方の入力ファイルの行が、同じように大文字小文字を区別せず並んでいなければならない。そうした順番で並べるには、sort -f を使えばよい。

-1 FIELD
     ファイル 1 では FIELD 番目のフィールドを共通フィールドとする (FIELD は正の整数)。

-2 FIELD
     ファイル 2 では FIELD 番目のフィールドを共通フィールドとする (FIELD は正の整数)。

-j FIELD
     -1 FIELD -2 FIELD と等価。

-o FIELD-LIST
-o auto
     キーワードの auto が指定されると、 join は各ファイルの最初の行を元にして、出力フォーマットを推測する。それは、デフォルトの出力フォーマットとほぼ同じだが、それだけでなく、各行に必ず同数のフィールドを出力するようにする。また、欠けているフィールドがあれば、-e オプションの指定する文字列で補う。余分なフィールドは除去する。

     auto が指定されていない場合は、FIELD-LIST のフォーマットに従って、各出力行を構成する。FIELD-LIST の各要素は、0 一文字か、M.N という形を取る。ここで、M はファイル番号 (FILE-NUMBER) であり、1 か 2 である。N はフィールド番号であり、正の整数である。

     0 というフィールド指定は、共通フィールドを指している。ほとんどの場合、 0 というフィールド指定と同じことが、共通フィールドを明示的に M.N で示すことでも、実現できるだろう。しかしながら、(-a オプションなり -v オプションなりを使用して)、対にならない行を表示する場合、対にならない行が両方のファイルに存在すると、FIELD-LIST で M.N をどう使おうとも、共通フィールドを指定できないのだ。join で共通フィールドの指定が常に可能になるように、POSIX は 0 というフィールド指定法を考案したのである。

     FIELD-LIST の各要素は、コンマ、または空白で区切られる。区切りに空白を使用するときは、シェルによって解釈されないように、たいていの場合引用符で囲む必要がある。たとえば、コマンド join -o 1.2,2.2 と join -o '1.2 2.2' は、同じ動作になる。

     FIELD-LIST の指定は、すべての出力行に適用される。これは、-a や -v オプションによって出力されるものにも当てはまる。

-t CHAR
     入出力のフィールドの区切りに、文字 CHAR を使用する。 CHAR は、入力ファイルに現れる一つ一つが、有意なものとして扱われる。 sort -t CHAR を -b なしで実行すれば、このオプションに対応する順序に行を並べることができる。 join -t '' を指定すると、行全体が共通フィールドとして考慮の対象になり、これは sort のデフォルトの動作に対応している。 -t '\0' を指定すると、ASCII NUL 文字がフィールドの区切りに使用される。

-v FILE-NUMBER
     通常の出力はせず、FILE-NUMBER (1 か 2 である) のファイルに存在する、対にならない各行を表示する。

     -z オプションを使用した場合、改行文字はフィールド・セパレータ扱いになる。

終了ステータス 0 は成功を示し、0 以外の値は失敗を示す。

文字操作
****

以下のコマンドは、個々の文字に対して操作を行う。

tr: 文字の置換、圧縮、削除を行う
==================

書式:

     tr [OPTION]... SET1 [SET2]

tr は標準入力を標準出力にコピーするが、その際に次の操作の一つを行う。

  * 文字を置換する。置換した結果に同一文字の連続があるときは、それを 1 文字に圧縮することもできる。

  * 同一文字の連続を 1 文字に圧縮する。

  * 文字を削除する。

  * 文字を削除する。さらに、削除した結果に同一文字の連続があるときは、それを 1 文字に圧縮する。

上記書式の SET1 と (もし、指定しているなら) SET2 の二つの引数には、順序が意味を持つ文字の集合を指定する。以下の説明で、それぞれ SET1、SET2 と呼ばれることになるそうした文字集合こそ、入力中に存在する文字のうちで tr が操作の対象とする文字群である。--complement (-c, -C) オプションを指定すると、SET1 の代わりにその補集合 (SET1 に含まれないすべての文字) が使われることになる。

現在のところ、tr が完全に対応しているのは、シングルバイト文字だけである。将来は、マルチバイト文字もサポートすることになるだろうが、そのときは、-C オプションで文字集合の補集合を作り、-c オプションで値 (訳注: いわゆる文字コード) の集合の補集合を作ることになるだろう。この区別が意味を持つのは、指定する値の中に文字ではないものがあるときだけだが、そういった事態は、マルチバイト・エンコーディングを使用しているロケールで、入力にエンコーディング・エラーが含まれるときしか起きそうにない。

このプログラムでは、--help や --version オプションも使える。 See Common options. なお、オプションは、オペランドの前で指定しなければならない。

終了ステータス 0 は成功を示し、0 以外の値は失敗を示す。

文字集合の指定
-------

SET1 や SET2 引数の書式は、正規表現の書式に似ているが、正規表現ではなく、文字のリストにすぎない。そうした文字列中のほとんどの文字は、単にその文字自身を表しているだけだが、便宜のため文字列中では以下に列挙する簡易記法も使うことができる。簡易記法によっては、以下で述べているように、 SET1 と SET2 のどちらか一方でしか使えないこともある。

バックスラッシュ・エスケープ

     以下のバックスラッシュ・エスケープ・シーケンスを認識する。

     \a
          Control-G (ベル).

     \b
          Control-H (バックスペース).

     \f
          Control-L (フォームフィード).

     \n
          Control-J (改行).

     \r
          Control-M (復帰).

     \t
          Control-I (水平タブ).

     \v
          Control-K (垂直タブ).

     \OOO
          1 から 3 桁の 8 進数 OOO によって表される値を持つ 8 ビット文字。 \400 は、\040 0 という連続する 2 バイトに解釈されるので、注意すること。

     \\
          1 個のバックスラッシュ。

     上記以外の 1 個の文字がバックスラッシュに続く場合は、その文字として解釈される。またバックスラッシュには、特別な意味を打ち消す働きもあるので、 [, ], *, - をエスケープするのにも使用できる。

範囲指定

     M-N という表記は、昇順で M から N までのすべての文字に展開される。 M は文字の照合順序で N より前のものでなければならず、さもないと、エラーになる。たとえば、0-9 は 0123456789 と同じである。

     System V の書式では、範囲は、角カッコ (square brackets）を使って囲むことになっているが、 GNU の tr はこの書式をサポートしていない。 System V の書式で指定した場合でも、置換が期待どおり行われることもあるが、それは、たいていの場合、角カッコが角カッコに置換されるからである。そうだとしても、予想外の動作をすることもあるので、角カッコの使用は避けた方がよい。たとえば、tr -d '[0-9]' は、数字だけでなく、角カッコも削除してしまう。

     昔からよく使われている範囲の指定法の多くが --- 正しい用法として認められているものでさえ --- 他のシステムで使えるとはかぎらない。たとえば、EBCDIC のホストでは、 A-Z という範囲の指定をしても、たいていの人が予想するような結果は得られないだろう。なぜなら、そこでは A から Z までが、ASCII におけるように隣り合ってはいないからである。POSIX 準拠の tr を使うことができるならば、この問題を回避する最善の方法は、文字クラスを使用することである (下記参照)。それができない場合は、範囲の要素を一つ一つ書き込むのが、一番可搬性のある方法だ (一番野暮ったい方法でもあるけれど)。

文字の繰り返し

     SET2 における [C*N] という表記は、文字 C の N 個の連続に展開される。従って、[y*6] は yyyyyy と同じである。また、SET2 における [C*] という表記は、SET2 を SET1 と同じ長さにするのに必要な数の C の連続に展開される。 N が 0 で始まっている場合は、 8 進数として扱われる。それ以外の場合は、10 進数である。

文字クラス

     [:CLASS:] という表記は、(あらかじめ定義されている) 文字クラス CLASS に属するすべての文字に展開される。展開された文字に特定の順序はないが、upper と lower の文字クラスは別で、この二つは、昇順に展開される。 --delete (-d) と --squeeze-repeats (-s) オプションの両方を指定している場合は、SET2 で任意の文字クラスを使用することができる。それ以外の場合 SET2 で使えるのは、lower と upper の文字クラスだけであり、それも、対応する文字クラスを (すなわち、upper に対しては lower、lower に対しては upper を)、 SET1 の対応する位置で指定しているときだけである。その場合は、大文字小文字の変換を指定していることになるわけだ。以下に文字クラスの名前を列挙する。なお、無効なクラス名を指定すると、エラーになる。

     alnum
          アルファベットの文字と数字。

     alpha
          アルファベットの文字。

     blank
          水平方向の空白 (Horizontal whitespace)。

     cntrl
          制御文字。

     digit
          数字。

     graph
          表示可能文字。空白を含まない (訳注: スペースもタブも改行も、すなわち、ホワイトスペースを一切含まない)。

     lower
          アルファベットの小文字。

     print
          表示可能文字。空白を含む (訳注: タブや改行は含まないが、スペース (0x20) は含む)。

     punct
          句読点 (訳注: 引用符なども含む)。

     space
          水平方向や垂直方向の空白 (Horizontal or vertical whitespace)。

     upper
          アルファベットの大文字。

     xdigit
          16 進数の数字。

等価クラス

     [=C=] という書式は、C と等価な文字のすべてに展開される。展開される文字の間に特定の順序はない。等価クラスは、比較的最近の発明であり、英語以外のアルファベットをサポートするためのものである。しかしながら、等価クラスを定義したり、何が等価クラスに含まれるかを決定したりする標準的な方法は存在しないようだ。そのため、GNU の tr は、等価クラスを十分に実装していない。各文字の等価クラスにはその文字しか含まれていないので、あまり使い道がない。

置換
--

tr は、SET1 と SET2 の両方が指定され、--delete (-d) オプションが指定されていない場合は、文字の置換を行う。 tr は入力の中に SET1 に存在する文字が現れるたびに、それを SET2 の対応する文字に置き換える。入力中の SET1 に存在しない文字は、読み飛ばして、変更しない。ある文字が SET1 中に 2 個以上存在し、SET2 中のそれに対応する文字がすべて同じでない場合、置換に使用するのは、最後の文字だけである。たとえば、次の二つのコマンドは、同じ動作をする。

     tr aaa xyz
     tr a z

tr がよく使われるのは、アルファベットの小文字を大文字に変換するときである。それには、いろいろな方法がある。例を三つほど挙げてみる。

     tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ
     tr a-z A-Z
     tr '[:lower:]' '[:upper:]'

ただし、上記の a-z のような範囲指定の使用は、可搬性がないことに注意していただきたい。

tr で置換を行う際には、普通 SET1 と SET2 を同じ長さにする。SET1 が SET2 より短いと、SET2 の後尾にある余分な文字が無視されることになる。

逆に、SET1 が SET2 より長い場合は、可搬性がなくなる。 POSIX の規定では、結果は未定義なのだ。こうした場合、BSD の tr は、 SET2 の最後の文字を必要なだけ繰り返して、SET2 が SET1 と同じ長さになるようにする。 System V の tr は、SET1 を SET2 と同じ長さに切り詰める。

デフォルトでは、GNU 版の tr は、この問題を BSD の tr と同じやり方で処理する。そして、--truncate-set1 (-t) オプションが指定されている場合のみ、System V の tr のように処理するのである。このオプション (--truncate-set1) は、置換以外の操作では無視される。

この問題で System V の tr の動作を選ぶと、比較的よく使われる BSD 式の次の慣用表現が使えなくなる。

     tr -cs A-Za-z0-9 '\012'

なぜなら、System V の動作では、アルファベットと数字以外のすべての文字を改行文字に変換するのではなく、ゼロバイトしか (ASCII NUL 文字、それが SET1 の補集合の最初の要素である) 改行文字に変換しないからだ。

ちなみに、上記の慣用表現は、システムによってはうまく動作しない。なぜなら、範囲指定を使っているからであり、また、改行の 8 進数によるコードを 012 と決め込んでいるからでもある。tr が POSIX に準拠しているなら、以下の方が、よりよい書き方である。

     tr -cs '[:alnum:]' '[\n*]'

連続する文字の圧縮と文字の削除
---------------

--delete (-d) オプションのみが指定された場合、tr は、 SET1 に存在する文字が入力中にあれば、それを削除する。

--squeeze-repeats (-s) オプションのみが指定され、置換が要求されていない場合、 tr は、SET1 に存在する文字が入力中に連続して現れるたびに、その部分をただ 1 個のその文字に置き換える。

--delete と --squeeze-repeats の両方が指定された場合、 tr は、まず SET1 を使って削除を行い、その後で、残っている文字に対して、SET2 を使って連続する同一文字の圧縮を行う。

--squeeze-repeats オプションは、置換の際に使用することもできる。その場合、tr は、まず置換を実行し、その後で、置換結果に対して、 SET2 を使って連続する同一文字の圧縮を行う。

例をいくつか挙げて、オプションの様々な組み合わせを説明する。

  * すべてのゼロバイトを削除する。

          tr -d '\0'

  * 入力中のすべての単語 (訳注: 空白などで前後を区切られた文字列) を 1 行に 1 個づつ書き出す。このコマンドは、アルファベットと数字以外のすべてを改行文字に変換し、さらに、改行が連続して現れるそれぞれの箇所を 1 個の改行文字に圧縮している。

          tr -cs '[:alnum:]' '[\n*]'

  * 連続する改行文字が現れるごとに、それを一個の改行文字に変換する。すなわち、空行を除去する。

          tr -s '\n'

  * 文書中の単語の重複を探し出す。たとえば、 改行を挟んで同じ単語を繰り返して、 ``the the'' のように書いてしまうとことは、よくあることである。以下の Bourne シェルのスクリプトは、次のように動作する。まず、句読点や空白文字が 1 個以上続けて現れるたびに、それを 1 個の改行文字に置き換える。そうすることで、単語が 1 行に 1 個づつ出力されることになるわけだ。次には、すべての大文字を小文字に変換する。そして、最後に、uniq を -d オプション付きで実行して、重複した単語のみを書き出すのである。

          #!/bin/sh
          cat -- "$@" \
            | tr -s '[:punct:][:blank:]' '[\n*]' \
            | tr '[:upper:]' '[:lower:]' \
            | uniq -d

  * 文字のちょっとした集団を削除するのは、たいていの場合ごく簡単である。たとえば、a, x, M という文字をすべて消すには、次のようにするだけでよい。

          tr -d axM

     ところが、削除する文字の一つに  - があると、- は特殊な意味をもっているので、厄介なことになりかねない。上記と同様の作業を行うけれど、今度は - という文字もついでにすべて削除するとしよう。 tr -d -axM をやってみるかもしれないが、うまく行かないだろう。 tr が -a をコマンドライン・オプションとして解釈しようとするからである。それではと、ハイフンを文字列の内側に入れてみることもできる。 tr -d a-xM のようにだ。だが、これもうまく行きそうにない。 tr が a-x を 3 個の文字としてではなく、a...x という文字の範囲として解釈することになるからだ。この問題を解決する方法の一つは、ハイフンを文字のリストの最後に置くことである。

          tr -d axM-

     あるいは、-- を使って、オプション処理はここで終わりと明示することもできる。

          tr -d -- -axM

     より普遍的な方法は、等価クラスの記法  [=c=] を、c を - で (あるいは、他の任意の文字で) 置き換えて使うことである。

          tr -d '[=-=]axM'

     上記の例では、角カッコがシェルによって解釈されないように、シングルクォートを使っていることに注意していただきたい。

expand: タブをスペースに変換する
====================

expand は指定された各 FILE の内容を標準出力に書き出し、その際にタブ文字を適切な数のスペースに変換する。 FILE が指定されていない場合や、FILE として - が指定されている場合は、標準入力を対象にする。

書式:

     expand [OPTION]... [FILE]...

デフォルトでは、expand はすべてのタブをスペースに変換する。バックスペース文字は、出力にそのまま残しておく。バックスペースには、タブ幅を計算する際に、桁数を減らす働きがあるのだ。デフォルトの動作は、 -t 8 を指定したときと同じである (タブ位置を 8 桁ごとにする)。

このプログラムでは以下のオプションが使用できる。参照: Common options.

-t TAB1[,TAB2]...
--tabs=TAB1[,TAB2]...
     タブ位置 (tab stop) が一つだけ指定された場合には、 (訳注: 入力行における) タブ位置が TAB1 桁ごとあるものとする (デフォルトは 8 桁ごと)。それ以外の場合は、タブ位置を TAB1, TAB2, ... 桁目に置き (行頭を 0 桁目として数える)、指定された最後のタブ位置より後ろにあるタブは 1 個のスペースで置き換える。タブ位置の指定は、コンマで区切ってもよく、空白で区切ってもよい。

     互換性を考慮して、GNU の expand は、-TAB1[,TAB2]... という、このオプションの古い書式も認めている。新しいスクリプトでは、 -t TAB1[,TAB2]... の方を使うべきである。

-i
--initial
     各行の行頭にあるタブ群だけを (言い換えれば、スペースでもタブでもないどんな文字よりも前にある 1 個以上のタブだけを) スペースに変換する。

終了ステータス 0 は成功を示し、0 以外の値は失敗を示す。

unexpand: スペースをタブに変換する
======================

unexpand は、指定された各 FILE の内容を標準出力に書き出し、その際に各行の先頭にある複数の空白 (blank) を、必要な数のタブ文字に変換する。 FILE が指定されていない場合や、FILE として - が指定されている場合は、標準入力を対象にする。デフォルトの POSIX ロケールでは、空白 (blank) とは、スペースかタブのことである。他のロケールでは、ほかの空白文字が追加されているかもしれない。

書式:

     unexpand [OPTION]... [FILE]...

デフォルトでは、unexpand が変換するのは、各行の行頭にある複数の空白だけである (言い換えれば、空白以外のどんな文字よりも前にある複数の空白だけ)。バックスペース文字は、出力にそのまま残しておく。バックスペースには、タブ幅を計算する際に、桁数を減らす働きがあるのだ。デフォルトでは、タブ位置は 8 桁ごとに置かれる。

このプログラムでは以下のオプションが使用できる。参照: Common options.

-t TAB1[,TAB2]...
--tabs=TAB1[,TAB2]...
     タブ位置 (tab stop) が一つだけ指定された場合には、 (訳注: 入力行における) タブ位置をデフォルトの 8 桁ごとではなく、TAB1 桁ごとに設定する。それ以外の場合は、タブ位置を TAB1, TAB2, ... 桁目に置き (行頭を 0 桁目として数える)、指定された最後のタブ位置より後ろにある空白は、変換せず、そのままにする。タブ位置の指定は、コンマで区切ってもよく、空白で区切ってもよい。このオプションを指定すると、-a オプションが自動的に設定される。

     (訳注: 一例を挙げておく。たとえば、-t 8,12 なら、入力行は、先頭を 0 桁目として、8 桁目、12 桁目にタブ位置があると見なされる。そこで、先頭に 12 個のスペースがある行に対して unexpand -t 8,12 を行うと、空白がタブ 2 個に変換される。出力におけるタブ位置はデフォルトのままなので、出力ではその行は、 0 から数えて 16 桁目から文字が始まることになる。)

     互換性を考慮して、GNU の unexpand は、 -TAB1[,TAB2]... という、このオプションの古い書式も認めている。そちらを使う場合は、タブ位置を必ずコンマで区切らなければならない。なお、-t とは違って、この古いオプションは、-a を自動的に設定しない。新しいスクリプトでは (訳注: 古い書式と同じ動作をさせたい場合)、古い書式に代えて、--first-only -t TAB1[,TAB2]... を使うべきである。

-a
--all
     空白の連続が、行の中で空白以外の文字の後ろにある場合でも、タブ位置の直前にある 2 個以上の空白の連続は、すべて変換する。

終了ステータス 0 は成功を示し、0 以外の値は失敗を示す。

ディレクトリの一覧表示
***********

この章では、ls とその変種の dir 及び vdir について説明する。こうしたコマンドは、ファイルに関する情報を一覧表示する。

ls: ディレクトリの内容を一覧表示する
====================

ls プログラムはファイルに関する情報を一覧表示する (ファイルは、いかなるタイプでもよく、ディレクトリでもよい)。オプションとファイルを示す引数は、ほとんどのコマンドと同様、どんな順番で指定しても構わない。

コマンドラインで指定したオプション以外の引数がディレクトリならば、 ls はデフォルトでは、そのディレクトリの内容を一覧表示する。その際、再帰的な表示はせず、名前が . で始まるファイルも表示しない。オプション以外の引数がディレクトリでなければ、単にそのファイルの名前を表示するのが、 ls のデフォルトの動作である。オプション以外の引数が一つも指定されていない場合は、カレントディレクトリを対象にし、あたかも . という引数を一つだけ付けて起動したかのように動作する。

デフォルトでは、出力を、現在のロケール設定に従って、アルファベット順でソートする (POSIX 以外のロケールを使用している場合は (たとえば、LC_ALL を en_US に設定している場合は)、ls の出力が、見慣れない順序で並んでいるかもしれない。そうした場合は、環境変数 LC_ALL を C にしてみるとよい。)。標準出力が端末の場合は、出力を多段組みで (訳注: すなわち、1 行に複数ファイルの形式で) 表示し、制御文字を疑問符として出力する (ソートは縦方向に行う)。それ以外の場合は、出力が 1 行 1 ファイルの形式になり、制御文字はそのまま手を加えずに出力する。

(訳注: 端末へ出力されるファイル名は、現在ではデフォルトのスタイルが、「制御文字を疑問符で」から別のものに変更されているかもしれない。詳しくは、「ファイル名のフォーマット」の節の --quoting-style の訳注をご覧いただきたい。)

ls はきわめて基本的なプログラムなので、長年の間にオプションがどんどん増えてしまった。以下のサブセクションでは、そうしたオプションについて説明している。各サブセクション内では、オプションを (大文字小文字を無視して) アルファベット順に並べている。このようにオプションをサブセクションに分けてはみたが、この分類法は完全なものではない。オプションの中には、ls の動作の複数の側面に作用するものもあるからである。

終了ステータス:

     0: 成功
     1: 軽微な問題 (たとえば、コマンドライン引数として指定されていない
        ファイルやディレクトリにアクセスできなかった場合。ディレクトリの
        内容を一覧表示しようとしたとき、その中にあるエントリが今まさに
        削除やリネームの最中だと、そういうことが起きる)
     2: 深刻なトラブル (たとえば、メモリの不足、無効なオプション、
        コマンドライン引数として指定されたファイルやディレクトリに
        アクセスできなかった場合、ディレクトリのループなど)

参照 Common options.

表示対象にするファイル
-----------

以下のオプションは、どんなファイルについて ls が情報を表示するかを決定する。デフォルトで ls が表示するのは、コマンドラインで指定されたファイルだが、ディレクトリが指定された場合は、その内容になる。ただし、ディレクトリの内容のうち、名前が . で始まるファイルは表示しない。

-a
--all
     ディレクトリの内容を表示する際、. で始まるファイル名も無視しない。

-A
--almost-all
     ディレクトリの内容を表示する際、. と .. は無視するが、それ以外の . で始まるいかなるファイル名も無視しない。--all (-a) オプションは、このオプションに優先する。

-B
--ignore-backups
     ディレクトリの内容表示において、~ で終わるファイルを無視する。このオプションは、--ignore='*~' --ignore='.*~' と同じである。

-d
--directory
     ディレクトリについても、ディレクトリ内容の一覧ではなく、他のタイプのファイルの場合と同じように、名前だけを表示する。また、--dereference-command-line (-H), --dereference (-L), --dereference-command-line-symlink-to-dir といったオプションが指定されていないかぎり、コマンドラインでシンボリックリンクが指定されても、それをたどらない。

-H
--dereference-command-line
     コマンドライン引数がシンボリックリンクを指定している場合、リンクそのものではなく、リンクが参照しているファイルの情報を表示する。

--dereference-command-line-symlink-to-dir
     原則としてシンボリックリンクの参照を行わないが、一つだけ例外がある。すなわち、コマンドライン引数がシンボリックリンクを指定し、それがディレクトリを指している場合は、リンクそのものではなく、そのディレクトリの情報を表示する。この動作は、リンクの参照に関係する他のオプションが全く指定されていないときの、 ls のデフォルトの動作である (リンクの参照に関係する他のオプションには、 --classify (-F), --directory (-d), -l, --dereference (-L), --dereference-command-line (-H) がある)。

--group-directories-first
     すべてのディレクトリをまとめてファイルの前に置き、その上で、選択したソート・キーを使って (--sort オプション参照)、ディレクトリとファイルをそれぞれ別々にソートする。別の言い方をすると、このオプションはソートする際の主キーを設定し、 --sort オプションが副キーを設定するということだ。ただし、 --sort=none (-U) を使ったりすると、このオプションは全く無効になる。

--hide=PATTERN
     ディレクトリの内容表示において、--all (-a) や --almost-all (-A) が同時に指定されていないかぎり、シェルのパターン PATTERN に名前がマッチするファイルを無視する。このオプションの動作は、--ignore=PATTERN とほぼ同じだが、--all (-a) や --almost-all (-A) が併せて指定されていると、効果がないという点が違う。

     このオプションは、シェルのエイリアスで使うと、便利かもしれない。たとえば、lx が ls --hide='*~' のエイリアスで、ly は ls --ignore='*~' のエイリアスだとしよう。その場合、lx -A というコマンドは、ファイル README~ を表示するが、 ly -A は表示しないことになる。

-I PATTERN
--ignore=PATTERN
     ディレクトリの内容表示において、シェルのパターン (正規表現ではない) PATTERN に名前がマッチするファイルを無視する。シェルの場合と同様、ファイル名の先頭にある . は PATTERN の先頭のワイルドカードとマッチしない。このオプションを二度以上使うと、便利なことがある。たとえば、

          $ ls --ignore='.??*' --ignore='.[^.]' --ignore='#*'

     最初のオプションは . で始まる 3 文字以上のファイル名を無視する。二番目のオプションは . で始まる二文字のファイル名のうち、 .. を除くすべて無視し、三番目のオプションは # で始まるファイル名を無視する。

-L
--dereference
     シンボリックリンクについてファイル情報を表示する際、リンクそのものではなく、リンクが参照しているファイルの情報を表示する。とは言え、このオプションを使用した場合でも、表示されるファイル名については、リンクそのものの名前のままであり、リンクが指しているファイルの名前にはならない。

-R
--recursive
     すべてのディレクトリの内容を再帰的に一覧表示する。

表示する情報
------

以下のオプションは、ls がどんな情報を表示するかに関係している。 ls がデフォルトで表示するのは、ファイル名だけである。

--author
     詳細形式でディレクトリ内容のリストを出力する際、各ファイルの作成者情報を表示する。 GNU/Hurd では、ファイルの作成者 (author) はファイルの所有者 (owner) と別人であることがあるが、他のオペレーティング・システムでは、両者は同一である。

-D
--dired
     詳細表示形式 (-l) と併せて使用すると、出力本体の後ろに以下のような追加の行を表示する。

          //DIRED// BEG1 END1 BEG2 END2 ...

     BEGN や ENDN は符号なしの整数であり、出力における各ファイル名の開始バイト位置と終了バイト位置を示している。このようにすることで、ファイル名に空白や改行のような普段使わない文字が含まれている場合でも、手の込んだ検索をするまでもなく、 Emacs が簡単にファイル名を見つけられるようにしているのである。

     ディレクトリを再帰的にリストしている場合には (-R)、各サブディレクトリ名のオフセットを記した同様の行も出力する。

          //SUBDIRED// BEG1 END1 ...

     そして最後に、次の形式の行を出力する。

          //DIRED-OPTIONS// --quoting-style=WORD

     ここで、WORD はクォートの方式である (see Formatting the file names)。

     実例を挙げてみる。

          $ mkdir -p a/sub/deeper a/sub2
          $ touch a/f1 a/f2
          $ touch a/sub/deeper/file
          $ ls -gloRF --dired a
            a:
            total 8
            -rw-r--r-- 1    0 Jun 10 12:27 f1
            -rw-r--r-- 1    0 Jun 10 12:27 f2
            drwxr-xr-x 3 4096 Jun 10 12:27 sub/
            drwxr-xr-x 2 4096 Jun 10 12:27 sub2/

            a/sub:
            total 4
            drwxr-xr-x 2 4096 Jun 10 12:27 deeper/

            a/sub/deeper:
            total 0
            -rw-r--r-- 1 0 Jun 10 12:27 file

            a/sub2:
            total 0
          //DIRED// 48 50 84 86 120 123 158 162 217 223 282 286
          //SUBDIRED// 2 3 167 172 228 240 290 296
          //DIRED-OPTIONS// --quoting-style=literal

     上記 //DIRED// 行の 2 個づつ組になっているオフセットは、次の 6 個の名前の区切りとなるバイト位置を示している (訳注: 別の言い方をするなら、出力の先頭からある名前の直前までのバイト数と、その名前の最後の文字までのバイト数を示している)。6 個の名前とは、すなわち f1, f2, sub, sub2, deeper, file である。 //SUBDIRED// の行のオフセットが示しているのは、次のディレクトリ名の区切りである。 a, a/sub, a/sub/deeper, a/sub2。

     下記の例では、5 番目の項目の名前 deeper を抜き出してみせている。この項目の名前は、217 と 223 のオフセットの組に対応している。

          $ ls -gloRF --dired a > out
          $ dd bs=1 skip=217 count=6 < out 2>/dev/null; echo
          deeper

     上記のファイル一覧表示では、deeper という項目の後ろにスラッシュが付いているが、オフセットが名前として選択しているのは、後ろのスラッシュを除いた部分であることに注目していただきたい。しかしながら、ls を --dired とともに --escape (短縮形は -b) のようなオプションを付けて実行し、名前に特殊文字が入っているファイルを処理の対象にする場合には、バックスラッシュがオフセットの示す範囲のうちに含まれることに注意しなければならない。

          $ touch 'a b'
          $ ls -blog --dired 'a b'
            -rw-r--r-- 1 0 Jun 10 12:28 a\ b
          //DIRED// 30 34
          //DIRED-OPTIONS// --quoting-style=escape

     引用符を付加するクォート方式を使用している場合には (たとえば、 --quoting-style=c)、引用符もオフセットの示す範囲に含まれる。そこで、そうしたクォート方式が、環境変数 QUOTING_STYLE によって選択されている可能性も考慮に入れておくべきだ。すなわち、--dired を使用するアプリケーションでは、コマンドラインで明示的に --quoting-style=literal オプションを指定するか (-N や --literal と指定しても同じことだ)、あるいは、エスケープされた名前を解析できるするようにしておくか、どちらかをするべきだということである。

--full-time
     詳細形式でディレクトリ内容のリストを生成し、日時の情報を省略なしで表示する。これは、--format=long を --time-style=full-iso と一緒に使うのと同じである (see Formatting file timestamps)。

-g
     詳細形式でディレクトリ内容のリストを生成するが、所有者情報は表示しない。

-G
--no-group
     詳細形式でディレクトリ内容をリスト表示する際に、グループ情報を表示しない (GNU 版以外の ls には、この動作がデフォルトのものがある。そこで、互換性のために、このオプションを用意している)。

-h
--human-readable
     各サイズの後ろに、メビバイトなら M といった、大きさを示す文字を付ける。 1000 ではなく、1024 の累乗が使われるので、M は 1,048,576 バイトを表している。このオプションは、--block-size=human-readable と同じである。1000 の累乗が使いたければ、"--si オプションを使用すればよい。

-i
--inode
     ファイル名の左側にそのファイルの inode 番号を表示する (inode 番号は、ファイル連続番号とか、インデックスナンバーとも呼ばれる。この番号は、ある特定のファイルシステムにある各ファイルを、一意に指し示す)。

-l
--format=long
--format=verbose
     各ファイルの名前のほかに、(訳注: 行頭から順に) ファイルのタイプ、ファイルのモードビット (訳注: 一般に「アクセス権」とか「許可属性」と言われるもの)、ハードリンク数、所有者名、グループ名、サイズ、タイムスタンプを表示する (see Formatting file timestamps)。タイムスタンプは、通常は更新日時 (訳注: いわゆる mtime) である。特定することのできない情報については、疑問符を表示する。

     通常、サイズは、桁を区切る記号を付けずに、バイト数で表示されるが、この表示法は変更することができる (see Block size)。たとえば、 -h オプションを指定すると、人間に読みやすい短縮表示になり、 --block-size="'1" を指定すると、現在のロケールの区切り記号で 3 桁ごとに区切ったバイト数が表示される。

     ディレクトリの内容をリストする場合は、対象となるディレクトリごとに、ファイルのリストの前に total BLOCKS という行を置く。ここで、BLOCKS は、そのディレクトリにあるすべてのファイルに割り当てられたディスク容量の合計である。現在のところブロックサイズはデフォルトでは 1024 バイトであるが、この値は変更することができる (see Block size)。 BLOCKS の計算では、各ハードリンクを別のものとして計算している。これはバグだと言えないこともない。

     ファイルタイプには、以下の文字の一つが使われる。

     -
          通常ファイル

     b
          ブロック・スペシャルファイル

     c
          キャラクタ・スペシャルファイル

     C
          ハイパフォーマンス (``contiguous data'') ファイル

     d
          ディレクトリ

     D
          ドア (Solaris 2.5 以上)

     l
          シンボリックリンク

     M
          オフライン (``migrated'') ファイル (Cray DMF)

     n
          ネットワーク・スペシャルファイル (HP-UX)

     p
          FIFO (名前付きパイプ)

     P
          ポート (Solaris 10 以上)

     s
          ソケット

     ?
          上記以外のファイルタイプ

     ファイルのモードビットの表示は、アクセス権を設定する際のシンボリックモードの仕様とほぼ同じである (see Symbolic Modes)。ただし、ls は、以下のように、複数のモードビットを一つにまとめて、アクセス権の各セットの 3 番目の文字で表現している。

     s
          set-user-ID ビットまたは set-group-ID ビットと、対応する実行ビットの両方が立っている場合。

     S
          set-user-ID ビットまたは set-group-ID ビットが立っているが、対応する実行ビットは立っていない場合。

     t
          削除制限フラグまたはスティキー・ビット (sticky bit) と、その他のユーザ (other) の実行ビットの両方が立っている場合。削除制限フラグは、スティッキー・ビットの別名である。 See Mode Structure.

     T
          削除制限フラグまたはスティキー・ビットが立っているが、その他のユーザの実行ビットが立っていない場合。

     x
          実行ビットが立っていて、上記のどれにも当てはまらない場合。

     -
          それ以外。

     ファイルのモードビットの後に続く 1 個の文字は、アクセス・コントロール・リスト (ACL) のような他のアクセス方式が、そのファイルに使われているかどうかを表している。ファイルのモードビットに続く文字が空白の場合は、他のアクセス方式を使用していないということである。表示文字が続く場合は、そうしたアクセス方式を使用しているということだ。

     GNU の ls は、SELinux セキュリティ・コンテキストを持つが、それ以外に他のアクセス方式を使用していないファイルを示すのに、ピリオド (.) を使う。

     それ以外で、ファイルが、標準以外のアクセス方式の何らかの組み合わせを使用している場合には、 + 文字が印として付く。

-n
--numeric-uid-gid
     詳細形式でディレクトリの内容をリストするが、所有者やグループの名前の代わりに、数字の user-ID や group-ID を表示する。

-o
     詳細形式でディレクトリの内容をリストするが、グループ情報を表示しない。これは、--format=long を --no-group と併せて使うのと同じである。

-s
--size
     各ファイルに対するディスク割り当て量をファイル名の左側に表示する。これはファイルが使用しているディスクスペースの量であり、普通はファイルのサイズより少し多いが、穴空きファイル (sparse file) の場合は、少ないこともある。

     通常、ディスク割り当て量は 1024 バイトを単位として表示されるが、これは変更することができる (see Block size)。

     ファイルが HP-UX のシステムから BSD のシステムに NFS マウントされている場合、このオプションで報告されるディスク使用量は、正確な値の半分である。それに対して、HP-UX システムの場合は、BSD システムから NFS マウントされているファイルについて、このオプションは正確な値の 2 倍の量を報告する。これは、HP-UX システムにある欠陥のせいであり、HP-UX の ls プログラムも、そのとばっちりを受けているのである。

--si
     各サイズにの後ろに、メガバイトなら M といった、SI 形式の略号を付ける。 1024 ではなく、1000 の累乗が使用されるので、M は 1,000,000 バイトを表している。このオプションは、--block-size=si と同じことである。1024 の累乗が使いたければ、-h や --human-readable を使用すればよい。

-Z
--context
     SELinux セキュリティ・コンテキストを表示する。ない場合は、? を表示する。-l オプションと一緒に使った場合は、サイズの左にセキュリティ・コンテキストを出力する。

出力のソート
------

以下のオプションは、ls が出力する情報を並べる際の順序を変更する。デフォルトでは、情報は文字コードによってソートされる (たとえば ASCII コード順)。

-c
--time=ctime
--time=status
     詳細表示形式 (たとえば、-l, -o) を使用しているときは、更新日時 (modification time) の代わりに、ステータス変更日時 (status change time、inode の ctime) を表示する。日時によって明示的にソートしているときや (--sort=time あるいは -t)、詳細表示形式を使用していないときは、ステータス変更日時によってソートする。

-f
     主な働きは、-U と同じで、ソートしないことである。すなわち、ファイルをリストする際、ファイルがディレクトリにどんな順序で格納されていようと、そのままの順序で出力する。それだけでなく、-a (すべてのファイルをリストする) を有効にし、-l, --color, -s を (-f より前で指定されていたら) 無効にする働きもある。

-r
--reverse
     どんな方法でソートされていようと、逆順にする。たとえば、ファイルを並べる際に、アルファベットの後ろから並べる、最新バージョンから先に並べる、サイズの小さいものから先に並べる、などなど。

-S
--sort=size
     ファイルのサイズによってソートし、大きいものから順に並べる。

-t
--sort=time
     更新日時 (modification time、inode の mtime) によってソートし、新しいものから順に並べる。

-u
--time=atime
--time=access
--time=use
     詳細表示形式 (たとえば、--format=long) を使用しているときは、最終アクセス日時 (last access time、inode の atime) を表示する。日時によって明示的にソートしているときや (--sort=time あるいは -t)、詳細表示形式を使用していないときは、アクセス日時によってソートする。

-U
--sort=none
     ソートを行わない。すなわち、ファイルをリストする際、ファイルがディレクトリにどんな順序で格納されていようと、そのままの順序で出力する (-f が行う、ソートに無関係な他のことは、何もしない)。このオプションは非常に大きなディレクトリを一覧表示するとき、ことのほか役に立つ。ソートを全くしないことで、作業速度が著しく向上するからである。

-v
--sort=version
     バージョン名とバージョン番号によってソートし、低いバージョンから順に並べる。デフォルトのソート方法と動作が似ているが、 10 進数の数字が連続する各部分を、インデックス番号やバージョン番号と見なし、(文字列としてではなく) 数値として取り扱う点が違う。 (see Details about version sort.)

-X
--sort=extension
     ディレクトリの内容をファイルの拡張子 (最後の . の後に続く文字) によってアルファベット順でソートする。拡張子のないファイルは、最初に並べられる。

バージョン・ソートの詳細
------------

ファイル名にはインデックス番号やバージョン番号が含まれていることがしばしばあるが、バージョン・ソートは、そうした状況に対処している。通常のソートでは、1 文字づつ文字の比較を行うので、結果がこちらの期待する順番にならないことがよくあるのだ。バージョン・ソートが特に役に立つのは、インデックス番号やバージョン番号を名前に含むファイルがたくさんあるディレクトリを一覧するときである。

     $ ls -1            $ ls -1v
     abc.zml-1.gz       abc.zml-1.gz
     abc.zml-12.gz      abc.zml-2.gz
     abc.zml-2.gz       abc.zml-12.gz

バージョン・ソートにおける文字列の比較は、次のように行われる。 VER1 と VER2 がバージョン番号で、PREFIX (前置部分) と SUFFIX (後置部分) が文字列だとしよう (SUFFIX は正規表現の (\.[A-Za-z~][A-Za-z0-9~]*)* にマッチするもの)。その場合、VER1 < VER2 ならば、``PREFIX VER1 SUFFIX'' から構成される名前は ``PREFIX VER2 SUFFIX'' より前に来る。

数字の部分の先行する 0 は無視されることにも注意していただきたい。

     $ ls -1            $ ls -1v
     abc-1.007.tgz      abc-1.01a.tgz
     abc-1.012b.tgz     abc-1.007.tgz
     abc-1.01a.tgz      abc-1.012b.tgz

この機能は gnulib の filevercmp 関数を使って実装されている。そこで、知っておいた方がよい注意事項がいくつかある。

  * LC_COLLATE は無視される。そのため、ls -v や sort -V は、数値ではない PREFIX (前置部分) を、LC_COLLATE ロケール・カテゴリが C に設定されているかのようにソートする。

  * SUFFIX (後置部分) に上記の正規表現がマッチしてくれないことがある。従って、以下の例は、期待通りの順序ではないかもしれない。

          abc-1.2.3.4.7z
          abc-1.2.3.7z

          abc-1.2.3.4.x86_64.rpm
          abc-1.2.3.x86_64.rpm

出力全体の形式
-------

以下のオプションは出力全体の見かけに影響を及ぼす。

-1
--format=single-column
     1 行 に 1 ファイルを表示する。標準出力が端末でないときの ls のデフォルトである。ファイル名中に改行文字があっても、それをそのまま出力してしまわないようにするには、 -b や -q オプションも参照していただきたい。

     (訳注: -1 オプションを指定しても、標準出力が端末ならば、ファイル名中の改行文字を ? 記号で表示するか、ファイル名を shell-escape スタイルでクォートするか、どちらかをやってくれるはずだ。上の注意書きは、標準出力が端末でないときの話である。)

-C
--format=vertical
     ファイルのリストを多段組みで (訳注: すなわち、1 行に複数ファイルの形式で) 表示し、ソートは縦方向に行う。これは、標準出力が端末のときの ls のデフォルトである。dir コマンドにとっては、これが常にデフォルトになる。GNU の ls は、できるだけ少ない行数でできるだけ多くのファイルを表示するために、段の幅を可変にしている。

--color[=WHEN]
     ファイルのタイプを区別するためにカラー表示を使用するかどうかを指定する。 WHEN は省略してもよく、以下の一つでもよい。

       * none カラー表示を全く使用しない。これがデフォルトである。

       * auto 標準出力が端末の場合のみ、カラー表示を使用する。

       * always 常にカラー表示を使用する。

     WHEN を付けずに --color を指定するのは、"--color=always と同じことである。カラー表示にしたファイルのリストをパイプで more や less のようなページャに送ると、たいての場合、判読に苦しむ羽目になる。ただし、more -f を使うと、うまく行くようだ。(訳注: 訳者の手元では、 less -R や lv -c で一応問題なくカラー表示ができているようだ。)

     留意すべきは、--color オプションを使用すると、大量のファイルがあるディレクトリで ls を実行したとき、目に見えて動作速度が低下するかもしれないことである。これは、カラー表示のデフォルトの設定では、ls は、リストするファイルを一つづつ stat システムコールで調べる必要があるからだ。とは言え、ファイルタイプのカラー表示はおおむね使用したいけれど、他の色付けオプションは使わなくてもよいこともある (たとえば、実行属性、リンク切れ、スティッキー・ビット、その他のユーザの書き込み権限、ケーパビリティなどは、色で表示しなくてもよい)。その場合は、こんなふうに、dircolors コマンドを使用して、環境変数 LS_COLORS を設定すればよい。

          eval $(dircolors -p | perl -pe \
            's/^((CAP|S[ET]|O[TR]|M|E)\w+).*/$1 00/' | dircolors -)

     そうすれば、dirent.d_type が使えるファイルシステムなら、 ls は各コマンドライン引数に対してたった一回だけ stat システムコールを行うだけですむようになる。

-F
--classify
--indicator-style=classify
     各ファイル名の後ろに、ファイルタイプを示す 1 文字を付ける。通常ファイルの場合も、実行可能ファイルならば、* を後置する。ファイルタイプの指標は、ディレクトリならば /、シンボリックリンクならば @、FIFO ならば |、ソケットならば =、ドアならば > であり、通常ファイルを表す指標はない。なお、--dereference-command-line (-H), --dereference (-L), --dereference-command-line-symlink-to-dir といったオプションが指定されていないかぎり、コマンドラインで指定されたシンボリックリンクをたどることはない。

--file-type
--indicator-style=file-type
     各ファイル名の後ろに、ファイルタイプを示す 1 文字を付ける。 -F に似ているが、こちらは、実行ファイルに指標を付けない。

--indicator-style=WORD
     ファイル名の後ろに指標文字を付けるとき、WORD というスタイルを使用する。 WORD には次のものがある。

     none
          指標文字を全く付けない。これがデフォルトである。

     slash
          ディレクトリの後ろに / を付ける。これは、-p オプションと同じである。

     file-type
          ディレクトリ、シンボリックリンク、FIFO、ソケットの後ろに、それぞれ /, @, |,  = を付け、通常ファイルの後ろには何も付けない。これは、--file-type オプションと同じである。

     classify
          実行可能な通常ファイルの後ろに * を付ける。それ以外は、 file-type の場合と同じ動作をする。これは、-F や --classify オプションと同じである。

-k
--kibibytes
     デフォルトのブロックサイズを標準の値の 1024 バイトに設定する。そのとき、環境変数でそれ以外のどんな値が設定されていても、それを上書きする (see Block size)。このオプション自身も、 --block-size, --human-readable (-h), --si オプションがあれば、それによって上書きされる。

     --kibibytes (-k) オプションが影響を及ぼすのは、-l などのオプションが書き出すディレクトリごとのブロック数や、--size (-s) オプションが表示するディスク割り当て量に対してである。 -l の表示するファイルサイズには影響を及ぼさない。

-m
--format=commas
     ファイルを横に並べ、各行に収まる範囲でできるだけ多くの項目を表示する。ファイル同士は ,  (コンマとスペース) で区切る。

-p
--indicator-style=slash
     ディレクトリ名の後ろに / を付ける。

-x
--format=across
--format=horizontal
     ファイルのリストを多段組みで (訳注: すなわち、1 行に複数ファイルの形式で) 表示し、ソートは横方向に行う。

-T COLS
--tabsize=COLS
     タブ位置が COLS 桁ごとにあると想定する。デフォルトは 8 桁ごと。 ls は効率を考慮し、使えるときはタブを出力で使用する。 COLS が 0 の場合は、タブを使用しない。

     端末エミュレータの中には、ASCII 以外のバイトが前にあると、列をタブ位置の右にきちんと揃えてくれないものがあるかもしれない。この問題を回避するには、-T0 オプションを使うか、環境変数 TABSIZE=0 を設定するかして、列を揃えるのにタブではなく、スペースを使うよう、ls に指示すればよい。

-w COLS
--width=COLS
     スクリーンの横幅が COLS 桁だと想定する。デフォルトの値は、可能ならば端末の設定から取得する。取得できないときは、環境変数 COLUMNS が設定されていれば、それを使用する。それも設定されていないときのデフォルトの値は 80 である。 COLS の値を 0 にすると、出力行の長さに制限がなくなる。その場合、ただ一行の出力中で各項目を分離するのは、タブではなく、スペースになる。

タイムスタンプのフォーマット
--------------

デフォルトでは、ファイルのタイムスタンプは短縮形式で表示される。すなわち、最近のタイムスタンプ以外は、Mar 30  2002 といった日付表示になり、最近のタイムスタンプは、Mar 30 23:45 といった年度なしの日付と時刻の表示になる。この書式は、後で詳しく述べるように、使用しているロケールによっては違ったものになるかもしれない。

タイムスタンプは、ここ 6 ヶ月以内のもので、未来の日付が付いていなければ、最近 (recent) として扱われる。今日の日付のタイムスタンプが、最近用の書式で表示されない場合、そのタイムスタンプは未来扱いされている。それは、おそらく時計に狂いが生じているということであり、make のような、ファイルのタイムスタンプに頼っているプログラムは、まともに動かないかもしれない。

タイムスタンプは、タイムゾーンのルールに従って表示されるが、そのルールを指定しているのは、環境変数 TZ である。 TZ が設定されていない場合は、システムのデフォルトのルールに従って表示される。 See Specifying the Time Zone with TZ (The GNU C Library Reference Manual).

以下のオプションは、ファイルのタイムスタンプの表示方法を変更する。

--time-style=STYLE
     タイムスタンプを STYLE 形式で表示する。 STYLE は以下の一つでなければならない。

     +FORMAT
          FORMAT を使って、タイムスタンプを表示する。その場合、FORMAT は、date コマンドの書式引数と同じように解釈される (see date invocation)。たとえば、--time-style="+%Y-%m-%d %H:%M:%S" と指定すると、 ls の表示するタイムスタンプは、2002-03-30 23:45:56 のようになる。date の場合と同様、FORMAT の解釈は、LC_TIME ロケール・カテゴリの影響を受ける。

          FORMAT に改行で分離された二つの書式文字列がある場合、前半は最近のファイル以外に使用され、後半は最近のファイルに使用される。出力される列をきちんと揃えたければ、二つの書式のどちらかに、空白をいくつか入れる必要があるかもしれない。

     full-iso
          タイムスタンプを省略なしで表示する。すなわち、ISO 8601 の日付、時刻、タイムゾーンという構成要素を nanosecond (10 億分の 1 秒) の精度で使用するわけだ。一例を挙げると、2002-03-30 23:45:56.477817180 -0700 といった表示になる。この形式は、+%Y-%m-%d %H:%M:%S.%N %z と同じである。

          これが有用なのは、タイムスタンプが、オペレーティング・システムから取得できる時間関係のすべての情報を含んでいるからである。たとえば、GNU の make は、あるファイルが古いかどうかを判定するのに、省略なしのタイムスタンプを使用している。そのため、この情報が、make の動作を説明するために役立つことがあるのである。

     long-iso
          ISO 8601 の日付と時刻の構成要素を分の単位まで表示する。たとえば、 2002-03-30 23:45。このタイムスタンプは、full-iso タイムスタンプより短く、日常作業にはたいてい十分である。この形式は +%Y-%m-%d %H:%M と同じである。

     iso
          最近以外のタイムスタンプでは、ISO 8601 の日付を表示し (たとえば 2002-03-30 )、最近のタイムスタンプでは、 ISO 8601 風の月・日・時・分を表示する (たとえば 03-30 23:45)。この形式は、long-iso の形式に比べて見かけがよくないが、より狭いスペースでほぼ同量の情報を伝えており、また、簡潔なので ls の出力を伝統的な 1 行 80 桁の出力行に納めるのに都合がよい。 ls を実行する以下の二つの方法は、同じことである。

               newline='
               '
               ls -l --time-style="+%Y-%m-%d $newline%m-%d %H:%M"
               ls -l --time-style="iso"

     locale
          タイムスタンプをロケール依存形式で表示する。たとえば、フィンランド語のロケールだと、最近以外のタイムスタンプを maalis 30  2002 のように表示し、最近のタイムスタンプは maalis 30 23:45 のように表示するかもしれない。ロケール依存のタイムスタンプは、概して iso のタイムスタンプより長くなるし、ロケールごとの規則の違いは非常に大きいので、プログラムによる解析がずっと難しくなる。だが、こちらの方がわかりやすい人も大勢いる。

          タイムスタンプの書式を決めているのは、LC_TIME ロケール・カテゴリである。デフォルトの POSIX ロケールでは、Mar 30  2002 や Mar 30 23:45 といったタイムスタンプを使っている。 POSIX ロケールでは、ls を実行する次の二つの方法は、同じことである。

               newline='
               '
               ls -l --time-style="+%b %e  %Y$newline%b %e %H:%M"
               ls -l --time-style="locale"

          しかし、他のロケールでは動作が違う。たとえば、ドイツ語のロケールだと、 --time-style="locale" は --time-style="+%e. %b %Y $newline%e. %b %H:%M" とおそらく同じになり、30. Mär 2002  や 30. Mär 23:45 といったタイムスタンプを生成するだろう。

     posix-STYLE
          LC_TIME ロケール・カテゴリが POSIX なら、POSIX ロケールのタイムスタンプを表示し、それ以外なら、STYLE 形式のタイムスタンプを表示する。たとえば、posix-long-iso という指定は、POSIX ロケールでは Mar 30  2002 や Mar 30 23:45 といったタイムスタンプを表示し、それ以外のロケールでは 2002-03-30 23:45 といったタイムスタンプを表示する。

--time-style オプションのデフォルト値は、環境変数 TIME_STYLE を使って指定することができる。TIME_STYLE が設定されていない場合、デフォルトの形式は locale である。GNU Emacs のバージョン 21.3 以降では、ls の --dired オプションを使用しており、従って、どんな日付のフォーマットでも解析することができる。しかし、Emacs 21.1 や 21.2 を使っていて、POSIX 以外のロケールを指定している場合は、 TIME_STYLE="posix-long-iso" を設定する必要があるかもしれない。

ある種のサービス不能化攻撃 (denial-of-service attacks) を回避するため、 1000 バイトより長くなりそうなタイムスタンプは、エラーとして処理されることがある。

ファイル名のフォーマット
------------

以下のオプションは、ファイル名の表示方法を変更する。

-b
--escape
--quoting-style=escape
     ファイル名中の非表示文字を、C 言語で使うような、バックスラッシュにアルファベットや 8 進数を続ける方法を使用して、クォートする (訳注: このオプションでは、タブや改行だけでなく、空白 (Ox20) もバックスラッシュでクォートされる)。

-N
--literal
--quoting-style=literal
     ファイル名をクォートしない。とは言え、ls では、出力先が端末の場合は、 --show-control-chars が指定されていないかぎり、非表示文字を疑問符として表示するぐらいのことは行う。

-q
--hide-control-chars
     ファイル名中の非表示文字に代えて、疑問符を表示する。この動作は、出力先が端末で、プログラムが ls の場合のデフォルトである。

     (訳注: このオプションの現在の動作は変わっているかもしれない。すなわち、出力先が端末以外の場合は、上記の通り、非表示文字を疑問符で表示するが、出力先が端末の場合は、非表示文字を疑問符ではなく、$'' という形で表示し、空白 (0x20) を含むファイル名はファイル名全体をシングルクォートで囲むかもしれない。 --quoting-style の説明の末尾の訳注もご覧になっていただきたい。)

-Q
--quote-name
--quoting-style=c
     ファイル名をダブル・クォートで囲み、非表示文字を C 言語と同じやり方でクォートする。

--quoting-style=WORD
     ファイル名などの文字列には、通常使われない文字が含まれているかもしれない。このオプションを指定すると、WORD というスタイルを使って、そうした文字列をクォートすることになる。 WORD は、以下に挙げるものの一つでなければならない。

     literal
          文字列に手を加えず、そのまま出力する。これは、-N や --literal オプションと同じである。

     shell
          文字列にシェルのメタ文字がある場合や、出力が誤解を招くものになりそうな場合に、シェル向けのクォートを施す。このクォート方法は、bash のような POSIX 互換のシェルにはふさわしいものだが、 csh のような非互換のシェルでは、必ずしもうまく働くとはかぎらない。

     shell-always
          普通ならクォートが不要な場合でも、文字列にシェル向けのクォートを施す。

     shell-escape
          shell に似ているが、非表示文字のクォーティングに POSIX 提唱の $'' という書式を使用する。ほとんどのシェルに適している。 (訳注: ファイル名中に空白 (0x20) がある場合は、ファイル名全体をシングルクォートで囲む。)

     shell-escape-always
          shell-escape に似ているが、普通ならクォートが不要な場合でも、文字列にクォートを施す。

     c
          C 言語の文字列リテラルをクォートするときのように、文字列をクォートする。文字列をダブル・クォートで囲むことも行う。これは、-Q や --quote-name オプションと同じである。

     escape
          C 言語の文字列リテラルをクォートするときのように、文字列をクォートする。ただし、文字列をダブル・クォートで囲むことはしない。これは、-b や --escape と同じである。

     clocale
          C 言語の文字列リテラルをクォートするときのように、文字列をクォートする。ただし、文字列を囲む引用符には、ロケールにふさわしいものを使う。

     locale
          C 言語の文字列リテラルをクォートするときのように、文字列をクォートする。ただし、文字列を囲む引用符には、ロケールにふさわしいものを使い、さらに、デフォルトの C ロケールで言うと、"like this" ではなく、 'like this' のようにクォートを行う。この方が見栄えのよいディスプレイが多い。

     --quoting-style オプションのデフォルト値は、環境変数 QUOTING_STYLE によって指定することができる。この環境変数が設定されていない場合、デフォルトの値は、出力先が端末のときは shell-escape であり、端末以外のときは literal である。

     (訳注: 上記の説明からは、デフォルトの端末に対する出力のスタイルは、 shell-escape であるように読める。しかし、--hide-control-chars (-q) の説明や、ls の章全体の冒頭では、非表示文字を疑問符として表示するのが、デフォルトの端末に対する出力だと言っている。 info マニュアルの説明に少し混乱があり、部分的に古い記述が残っているらしい。実のところ、coreutils の開発元では、バージョン 8.25 あたりから、デフォルトの端末に対する出力を --quoting-style=shell-escape にしている。たとえば、ファイル名にタブが含まれている場合、オプションなしの ls は、aaa?bbb ではなく 'aaa'$'\t''bbb' のように端末に表示するのである。また、ファイル名中に空白がある場合は、ファイル名全体をシングルクォートで囲って、'/misc/xxx yyy' のように表示する。しかし、ディストリビューションによっては、バージョン 8.26 でも、デフォルトの端末に対する出力を --quoting-style=literal にしていることもある。その方が見やすいかもしれないので、それも一見識だと思う。端末に対するデフォルトの出力や -q オプションの動作が、ご自分のところではどうなっているか、一度お確かめになっておくとよい。)

--show-control-chars
     ファイル名中の非表示文字に手を加えず、そのまま出力する。この動作は、出力先が端末ではない場合や、プログラムが ls ではない場合のデフォルトである。

     (訳注: 開発元配布のバージョン 8.26 では、--show-contrls-chars を指定した場合も、出力先が端末だと、非表示文字を $'' の書式で表示している。出力先が端末以外なら、上の説明どおり、非表示文字がそのまま出力される。しかし、ディストリビューション配布の ls では、出力先が端末の場合に上記説明通りの動作をするものもある。これも、お手元で実際の動作を確かめておいていただきたい。)

dir: ディレクトリの内容を簡潔に表示する
======================

dir の動作は、ls -C -b と同じである。すなわち、デフォルトでは、ファイルのリストを多段組みで (訳注: 1 行に複数ファイルの形式で) 表示し、ソートは縦方向に行う。また、特殊文字は、バックスラッシュ・エスケープシーケンスを使って表示する。

See ls.

vdir: ディレクトリの内容を詳細に表示する
=======================

vdir の動作は、ls -l -b と同じである。すなわち、デフォルトでは、詳細形式でファイルをリストし、特殊文字は、バックスラッシュ・エスケープシーケンスを使って表示する。

See ls.

dircolors: ls のカラー設定
====================

dircolors は、ls (や dir など) でカラー出力をするのに必要な端末設定のためのシェルコマンドのシーケンスを出力する。通常、次のような形で使用される。

     eval "$(dircolors [OPTION]... [FILE])"

FILE が指定されていると、dircolors はそれを読み込んで、どのファイルタイプや拡張子に対してどの色を使うかを決定する。 FILE が指定されていない場合は、プログラムに埋め込まれているデータベースが使用される。そうした設定ファイルの書式について詳しいことを知りたかったら、 dircolors --print-database を実行してみるとよい。

ファイル ~/.dircolors が存在していたら、dircolors がそれを読み込むようにするには、以下の行を自分の ~/.bashrc に書き込めばよい (お気に入りのシェルが bash でないなら、適切に書き直すこと)。

     d=.dircolors
     test -r $d && eval "$(dircolors $d)"

dircolors の出力は、環境変数 LS_COLORS を設定するシェルコマンドである。どのシェルの文法にするかは、コマンドラインで指定することができる。指定しない場合は、環境変数 SHELL の値から dircolors が推測する。

このプログラムでは以下のオプションが使用できる。参照: Common options.

-b
--sh
--bourne-shell
     Bourne シェルのコマンドを出力する。これが、環境変数 SHELL が設定されていて、その値が csh や tcsh で終わっていないときのデフォルトである。

-c
--csh
--c-shell
     C シェルのコマンドを出力する。これは、環境変数 SHELL の値が、 csh や tcsh で終わっているときのデフォルトである。

-p
--print-database
     (プログラムに埋め込まれている) デフォルトのカラー設定データベースを出力する。この出力は、それ自体有効な設定ファイルであり、どういう設定が可能かについてかなり詳しく説明している。

終了ステータス 0 は成功を示し、0 以外の値は失敗を示す。

基本的なファイル操作
**********

この章では、基本的なファイル操作のためのコマンドを説明する。すなわち、コピー、移動 (名前の変更)、消去 (削除) といった操作である。

cp: ファイルやディレクトリをコピーする
=====================

cp はファイルをコピーする (もしそうしたければ、ディレクトリのコピーもできる)。コピーによって作られたファイルは、コピー元から全く独立したものになる。一つのファイルを別のファイルにコピーすることもできるし、好きなだけたくさんのファイルをコピー先のディレクトリに一遍にコピーすることもできる。

書式:

     cp [OPTION]... [-T] SOURCE DEST
     cp [OPTION]... SOURCE... DIRECTORY
     cp [OPTION]... -t DIRECTORY SOURCE...

  * ファイル名を二つ指定すると、cp は最初のファイルを 2 番目のファイルにコピーする。

  * --target-directory (-t) オプションを指定した場合や、あるいはそれを指定しないでも、最後のファイルがディレクトリであり、しかも --no-target-directory (-T) オプションを指定していない場合は、 cp は、各コピー元 (SOURCE) ファイルを、指定されたディレクトリにコピー元 (SOURCE) と同じ名前でコピーする。

ほとんどの場合、ファイルは読み込まれたとおりに書き出される。例外については、後述の --sparse オプションをご覧になっていただきたい。

デフォルトでは、cp はディレクトリをコピーしない。ただし、-R, -a, -r オプションを指定すると、 cp は再帰的なコピーを行う。すなわち、コピー元のディレクトリを段階的に下って、対応するコピー先のディレクトリにファイルをコピーすることになる。

コピー元がシンボリックリンクの場合、cp がリンクをたどるのは (訳注: すなわち、リンクそのものではなく、参照先の実ファイルをコピーするのは)、通常では、再帰的なコピーをしていないときか、あるいは、--link (-l) オプションが使用されているときだけである。このデフォルトの動作は、次に挙げるオプションによって変更することができる。 --archive (-a), -d, --dereference (-L), --no-dereference (-P), -H。こうしたオプションを二つ以上指定すると、cp は警告を出さず、最後のオプションで他のものを上書きする。

(訳注: 最近の cp では --link オプションの動作が変更されている。コピー元がシンボリックリンクの場合、coreutils-8.21 までは、デフォルトでは、シンボリックリンクのハードリンクを作っていたが、8.22 以後の cp では参照先ファイルのハードリンクを作るようになっている。)

コピー先がシンボリックリンクの場合、cp がリンクをたどるのは (訳注: すなわち、コピー元ファイルで、リンクそのものではなく、参照先のファイルを上書きするのは)、そのリンクが、存在する通常ファイルを指しているときだけである。それに対して、コピー先のシンボリックリンクがリンク切れしている場合は、cp は、デフォルトではコピーを拒否し、エラーメッセージを出して、実行に失敗する。そうした操作は、本質的に危険だからである。この動作は、伝統的な習慣や POSIX の仕様に反している。たとえリスクがあろうとも、リンク切れしたシンボリックリンクの参照先を cp が作成するようにしたいなら、環境変数 POSIXLY_CORRECT を設定すればよい。なお --backup や --link といったオプションが、コピーする前にコピー先ファイルの名前変更や削除を行う場合、 cp は、リンクが指しているファイルではなく、シンボリックリンクの名前変更や削除を行う。

デフォルトでは、cp がスペシャルファイルの内容をコピーするのは、再帰的なコピーをしていないときだけである。このデフォルトの動作は、 --copy-contents によって変更できる。

cp は通常、ファイルを自分自身にコピーすることを拒否するが、次の例外がある。 SOURCE と DEST が同一で、しかも、通常ファイルを指しているとき、 --force --backup オプションが指定されると、cp はバックアップファイルを作成することになる。バックアップファイルを標準のものにするか (訳注: ファイルの末尾にチルダ ~ が 1 個付く)、番号付きのものにするかは、いつもどおりの方法で指定できる (see Backup options)。存在するファイルに変更を加える前に、そのバックアップをちょっと作っておきたい場合、この動作は便利である。

このプログラムでは以下のオプションが使用できる。参照: Common options.

-a
--archive
     コピー元ファイルの構造と属性をコピー先でもできるだけ維持する (ただし、ディレクトリの内部構造を維持しようとはしない。そのため、コピー先で ls -U を実行すると、コピー元とは違った順序でファイルがリストされるかもしれない)。 SELinux コンテキストや拡張属性 (xattr) も維持しようとするが、そうした操作に失敗しても無視し、その旨エラーメッセージを表示することはない。エラーメッセージが少ないだけで、-dR --preserve=all と同じある。

--attributes-only
     コピー元ファイルの指定された属性のみを、コピー先にコピーする。コピー先ファイルがすでに存在している場合、その内容を変更することはない。属性のうち、何をコピーするかを決める方法については、--preserve オプションの項を見ていただきたい。

-b
--backup[=METHOD]
     See Backup options. そのままでは、上書きされるか、消去されてしまう各ファイルのバックアップを作成する。特殊な用法としては、次のものがある。force と backup の両方のオプションが指定されているとき、コピー元 (SOURCE) とコピー先 (DEST) が同じ名前で、しかも実在する通常ファイルを指していると、 cp はコピー元 (SOURCE) のバックアップを作成する。次のちょっとした Bourne シェルのスクリプトは、オプションのこの組み合わせの応用だが、便利である。

          #!/bin/sh
          # Usage: backup FILE...
          # リストされた各 FILE について GNU スタイルのバックアップを
          # 作成する
          fail=0
          for i; do
            cp --backup --force --preserve=all -- "$i" "$i" || fail=1
          done
          exit $fail

--copy-contents
     再帰的なコピーを行っている際に、スペシャルファイル (たとえば、FIFO やデバイスファイル) の内容を、操作対象が通常ファイルであるかのようにコピーする。要するに、コピー元の各ファイルからデータを読み込んで、それをコピー先に書き出そうとするわけである。このオプションを使うのは、ほとんどの場合誤りである。なぜなら、 FIFO や、通常 /dev ディレクトリにあるようなスペシャルファイルを対象にした場合、望ましくない結果を生ずることが珍しくないからだ。 cp -R --copy-contents は、FIFO や /dev/console のようなスペシャルファイルからデータを読み込もうとすると、たいていの場合、いつまでも無反応になるだろうし、/dev/zero をコピーしようとすれば、コピー先のディスクを溢れさせてしまうだろう。このオプションは、再帰的なコピーをするとき以外、効果を持たない。また、シンボリックリンクのコピーには影響しない。

-d
     シンボリックリンクをコピーする際、リンクが指しているファイルをコピーするのではなく、シンボリックリンクをシンボリックリンクとしてコピーする。また、コピー元において複数のファイルがハードリンクの関係にある場合、コピー先でもその関係を維持する。 --no-dereference --preserve=links と同じである。

-f
--force
     このオプションを付けずにコピーを行う場合、コピー先ファイルがすでに存在し、しかも書き込みモードでオープンできないと、コピーに失敗する。それに対して、--force を付けた場合は、コピー先ファイルがオープンできないと、 cp は、まずそれを削除してから、再度オープンを試みる。この動作は、--force と一緒に --link や --symbolic-link を使用した場合に行われる動作とは、違うことに注意していただきたい。後者の場合は、すでに存在するコピー先ファイルは一度もオープンされず、むしろ無条件で削除されるのである。--remove-destination の説明も参照すること。

     このオプションは、--interactive や -i オプションとは無関係である。どちらも他方の効果を無効にすることはない。

     --no-clobber や -n オプションを使用している場合、このオプションは無視される。

-H
     コマンドラインの引数がシンボリックリンクを指定している場合には、シンボリックリンクそのものではなく、それが指しているファイルをコピーする。とは言え、再帰的にディレクトリ・ツリーをたどっているときにシンボリックに出会った場合は、そのまま (つまり、シンボリックリンクとして) コピーする。

-i
--interactive
     ディレクトリ以外のファイルをコピーする際に、コピー先ファイルがすでに存在していると、プロンプトを出して、ファイルを上書きしてよいかどうか、ユーザに問い合わせる。 -i オプションは、-n オプションが前にあるとき、それを無効にする。

-l
--link
     コピー元がディレクトリ以外の場合、コピーする代わりに、ハードリンクを作成する。

-L
--dereference
     コピー元がシンボリックリンクの場合は、その参照先をコピーする。また、このオプションを使った場合、cp はシンボリックリンクを作ることができない。たとえば、コピー元のディレクトリ・ツリー中に (通常ファイルに対する) シンボリックリンクがあると、コピー先のディレクトリ・ツリーには、通常ファイルとしてコピーされることになる。

-n
--no-clobber
     存在するファイルを上書きしない。-n オプションは、-i オプションが前にあるとき、それを無効にする。このオプションと -b (--backup) オプションは、どちらか一方しか指定できない。

-P
--no-dereference
     コピー元がシンボリックリンクの場合、それが指しているファイルをコピーするのではなく、シンボリックリンクとしてコピーする。このオプションが作用を及ぼすのは、コピー元のシンボリックリンクに対してだけであり、コピー先に指定されたシンボリックリンクについては、可能なかぎり常に参照先がたどられる。

-p
--preserve[=ATTRIBUTE_LIST]
     コピー元ファイルの属性のうち、指定されたものをコピー先でも維持する。 ATTRIBUTE_LIST を指定する場合は、一つ以上の以下の文字列をコンマで区切ったリストでなければならない。

     mode
          ファイルのモードビット (訳注: 一般にアクセス権とか、許可属性と言われるもの) やアクセス・コントロール・リストを維持する。

     ownership
          所有者とグループを維持する。ほとんどの最近のシステムでは、ファイルの所有者を変更できるのは、しかるべき権限を持ったユーザだけである。また、一般ユーザがファイルのグループを維持できるのは、維持しようとするグループに、たまたまそのユーザが属しているときのみである。

     timestamps
          最終アクセス日時 (last access time) と最終更新日時 (last modification time) を、可能ならば、維持する。古いシステムでは、対象となるファイルがシンボリックリンクの場合、そうした属性を維持することができない。それに対して、最近のシステムでは、たいていのものが utimensat 関数を用意しているので、シンボリックリンクの場合でも、日時関係の属性維持が可能である。

     links
          コピー元のファイル同士が (ハードリンクであれ、シンボリックリンクであれ) リンクの関係にあるとき、コピー先の対応するファイル同士でも、その関係を維持する。ただし、-L や -H と一緒に使った場合、このオプションがシンボリックリンクをハードリンクに変更することがあるのに、注意していただきたい。一例を挙げる。

               $ mkdir c; : > a; ln -s a b; cp -aH a b c; ls -i1 c
               74161745 a
               74161745 b

          コピー元に注目していただきたい。b は、通常ファイル a を指すシンボリックリンクである。ところが、コピー先ディレクトリ c/ の二つのファイルは、ハードリンクになっている。 -a は --no-dereference を意味するのだから、シンボリックリンクがコピーされそうに思えるが、この場合は、後に続く -H が、コマンドライン引数の参照をたどるように cp に命じているので、cp には、同じ inode 番号を持った 2 個のファイルがコマンドラインで指定されているように見えるのである。さらに、-a は --preserve=links オプションを意味してもいるので、この働きによって、ハードリンクと認識された両ファイルの関係が、コピー先でも維持されることになるのである。

          次のものは、cp の -L を使った場合の類似例である。

               $ mkdir b c; (cd b; : > a; ln -s a b); cp -aL b c; ls -i1 c/b
               74163295 a
               74163295 b

     context
          ファイルの SELinux セキュリティ・コンテキストを維持する。それができないときは、詳細なエラーメッセージを出し、失敗のステータスで終了する。

     xattr
          ファイルの拡張属性を維持する。それができないときは、詳細なエラーメッセージを出し、失敗のステータスで終了する。 cp が xattr のサポートなしでビルドされている場合は、このオプションは無視される。 SELinux コンテキスト、ACL、ケーパビリティなどを xattr を使って実装している場合には、そうした属性もこのオプションによって、明示的な指定がない場合でも維持される。すなわち、--preserve=mode や --preserve=context を指定しないでも維持されるわけだ。

     all
          ファイルの属性をすべて維持する。上記のすべてを指定するのと同じことだが、 SELinux セキュリティ・コンテキストや拡張属性の維持に失敗しても、 cp の終了ステータスが変わらないという点が異なっている。 -a とは違って、Operation not supported 以外のすべての警告メッセージを出力する。

     ATTRIBUTE_LIST なしで --preserve を使用するのは、 --preserve=mode,ownership,timestamps と同じことである。

     このオプションを使わない場合、コピー先ファイルがすでに存在している場合は、その許可属性は変更されない。一方、新しくファイルが作成される場合は、対応するコピー元ファイルのモードを元にして、そこから set-user-ID ビット、set-group-ID ビット、スティッキー・ビットを落としたものが、各ファイルに付けられ、そしてさらに、オペレーティング・システムが umask なり、デフォルトの ACL なりを適用する。結果はより厳しいファイルモードになるかもしれない。 See File permissions.

--no-preserve=ATTRIBUTE_LIST
     指定された属性を維持しない。ATTRIBUTE_LIST の書式は、--preserve の場合と同じである。

--parents
     コピー先の各ファイル名を生成する際、出力先に指定されたディレクトリの末尾にスラッシュを付け、その後ろにコピー元として指定されたファイル名を付け足すことによってそれを行う。 cp に渡す最後の引数は、実在するディレクトリの名前でなければならない。一例を挙げる。

          cp --parents a/b/c existing_dir

     ファイル a/b/c を上記のコマンドでコピーすると、ファイル existing_dir/a/b/c が出来る。途中のディレクトリが存在していなければ、それも作成される。

-R
-r
--recursive
     ディレクトリを再帰的にコピーする。デフォルトでは、--link (-l) オプションが同時に使われていないかぎり、コピー元にあるシンボリックリンクの参照をたどることをしない。 --archive (-a), -d, --dereference (-L), --no-dereference (-P), -H などのオプションを参照。スペシャルファイルについては、コピーする際に、コピー元ファイルと同じファイル型のコピー先ファイルを作成する。 --copy-contents を参照。シンボリックリンクやスペシャルファイルのコピーに -r オプションを使用するのは、どのシステムでも通用することではない。 GNU 以外のシステムの中には、歴史的な理由から -r が、-L と --copy-contents を同時に指定するのと等価になっているものもあるからだ。また、シンボリックリンクをコピーするのに -R を使用するのも、-P も併せて指定しないかぎり、どのシステムでも通用することではない。デフォルトでシンボリックリンクの参照先をたどる実装が、POSIX で認められているからである。

--reflink[=WHEN]
     ファイルシステムがサポートしていれば、軽便コピー、すなわち、書き込み時コピー(copy-on-write (COW) copy) を行う。留意すべきは、これが成功した場合、コピー元とコピー先のファイルは、どちらかに対して変更が加えられるまで、ディスクの同じデータブロックを共有しているということである。従って、ディスク I/O エラーが起きて、片方のファイルのデータブロックが損傷を受ければ、もう一方のファイルも同じ被害に会う。

     WHEN の値には、次のうちの一つが使える。

     always
          デフォルトの動作である。copy-on-write がサポートされていない場合は、各ファイルについて失敗した旨を報告し、失敗を示すステータスで終了する。

     auto
          copy-on-write 操作がサポートされていない場合は、copy-on-write をあきらめて、標準のコピー動作を行う。

     このオプションは、--link, --symbolic-link --attributes-only オプションによって無効になるので、データをコピーする際の cp のデフォルト動作の設定に使用することができる。たとえば、次のエイリアスを使うと、cp は、ファイルシステムがサポートする範囲で、ディスクスペースの使用を最少に留めるようになる。

          alias cp='cp --reflink=auto --sparse=always'

--remove-destination
     コピー先ファイルがすでに存在する場合、その各々についてオープンを試みる前に、削除する (上述の -f と比較すること)。

--sparse=WHEN
     穴空きファイル (sparse file) とは、穴 (holes) を含むファイルである。穴というのは、物理的なディスクブロック上には存在しないゼロバイトの連続で、 read システムコールがそれを読む込むとき、ゼロの連続として扱うものである。バイナリ・ファイルには、連続するゼロバイトがたくさん含まれていることが多いので、この仕組みは、ディスクスペースを大いに節約してくれるし、動作速度の向上をもたらしてもくれる。デフォルトで cp は、かなり大雑把な発見的手法を使って、コピー元ファイルにある穴を検出し、対応するコピー先ファイルも穴空きファイルにする。なお、穴空きファイルにできるのは、通常ファイルだけである。

     WHEN の値には、次のうちの一つが使える。

     auto
          デフォルトの動作である。すなわち、コピー元が穴空きファイルなら、コピー先も穴空きファイルにしようとする。ただし、コピー先ファイルがすでに存在していても、通常ファイル以外を指している場合には、それを穴空きにしようとはしない。

     always
          たとえ、コピー元ファイルが穴空きファイルに見えなくても、十分に長いゼロバイトの連続があれば、その各々に対応する穴をコピー先ファイルに設けようとする。この動作が役に立つのは、コピー元ファイルが、穴空きファイルをサポートしていないファイルシステムにあるのに対し (たとえば、SGI IRIX 5.3 以前の efs ファイルシステム)、コピー先ファイルは穴空きファイルをしっかりサポートするタイプのファイルシステムにある場合である。穴を作ることができるのは、通常ファイルだけなので、コピー先が通常ファイル以外なら、 cp がそのファイルを穴空きにしようと試みることもない。

     never
          コピー先ファイルを穴空きにしない。これは、mkswap コマンドで使用するファイルを作成するときに役に立つ。そうしたファイルには、穴があってはならないからである。

--strip-trailing-slashes
     SOURCE 引数の後ろにスラッシュが付いていたら、それを削除する。 See Trailing slashes.

-s
--symbolic-link
     コピー元がディレクトリ以外の場合、コピーする代わりに、シンボリックリンクを作成する。出力先ファイルをカレント・ディレクトリに作成する場合を除いて、コピー元ファイルの名前は、すべて (/ で始まる) 絶対パス表記でなければならない。シンボリックリンクをサポートしていないシステムでは、このオプションはエラーメッセージを出すだけである。

-S SUFFIX
--suffix=SUFFIX
     -b によって作られる各バックアップファイルの後ろに SUFFIX を付ける。 See Backup options.

-t DIRECTORY
--target-directory=DIRECTORY
     DIRECTORY を出力先ディレクトリに指定する。 See Target directory.

-T
--no-target-directory
     最後のオペランドがディレクトリやディレクトリへのシンボリックリンクでも、それを特別扱いしない。 See Target directory.

-u
--update
     ディレクトリ以外のものをコピーする際、それがコピー先にも存在し、しかもその更新日時 (modification time) がコピー元と同じか、より新しい場合、コピーを行わない。コピー元からコピー先へタイムスタンプを引き継がせている場合には、コピー元のタイムスタンプの精度を、コピー先のファイルシステム、及びタイプスタンプの更新に使われるシステムコールの精度に落とした上で、比較を行う。これは、同じコピー元とコピー先のファイルに対して cp -pu コマンドを何回か実行する場合に、余計なコピー作業が起きるのを避けるためである。 --preserve=links が一緒に指定されている場合は (たとえば、cp -au だとそうなる)、そちらが優先されることになる。その結果、コピー元でファイルが処理される順番によっては、コピー元のハードリンクを反映させるために、コピー先のより新しいファイルが置き換えられることもある。

-v
--verbose
     コピーを行う前に、コピーするファイル名を表示する。

-x
--one-file-system
     あるファイルシステムでコピーを始めた場合、別のファイルシステムにあるサブディレクトリをスキップする。ただし、マウントポイントのディレクトリはコピーされる。

     このオプションと
     --preserve=context オプションは、どちらか一方しか指定できない。また、このオプションは --preserve=all や -a オプションに優先する。

終了ステータス 0 は成功を示し、0 以外の値は失敗を示す。

dd: ファイルの変換とコピー
===============

dd はファイルをコピーする (デフォルトでは、標準入力から標準出力へコピーする)。その際、入出力のブロックサイズを変更することができる。また、データ形式の変換を行いつつコピーすることもできる。

書式:

     dd [OPERAND]...
     dd OPTION

指定できるオプションは、--help と --version だけである。 See Common options.  dd では、以下のオペランドが使える。オペランドの書式の元になったのは、OS/360 の JCL (Job Control Language) の DD 文 (Data Definition statement) である。

if=FILE
     標準入力の代わりに、FILE から読み込む。

of=FILE
     標準出力の代わりに、FILE に書き出す。conv=notrunc が指定されていない場合、dd は、出力を開始する前に、FILE を 0 バイトに (あるいは、seek= で指定されたサイズに) 短縮する。

ibs=BYTES
     入力ブロックサイズを BYTES にする。dd が 1 ブロック BYTES バイトで読み込みを行うようになる。デフォルトは 512 バイトである。

obs=BYTES
     出力ブロックサイズを BYTES にする。dd が 1 ブロック BYTES バイトで書き出しを行うようになる。デフォルトは 512 バイトである。

bs=BYTES
     入力、出力、両方のブロックサイズを BYTES にする。dd が 1 ブロック BYTES バイトで読み書きを行うようになり、ibs や obs の指定は、あっても無効になる。なお、データ変換を行う conv オプションが指定されていない場合は、入力は、それがブロックサイズより小さくても、読み込まれるやいなや、出力にコピーされることになる。

cbs=BYTES
     変換ブロックサイズを BYTES にする。可変長のレコードを固定長のレコードに変換するときや (conv=block)、その逆を行うとき (conv=unblock)、固定長レコードの長さとして BYTES の値を使用する。

skip=N
     入力ファイルで ibs バイトのブロックを N 個読み飛ばしてから、コピーを行う。iflag=skip_bytes が指定されている場合は、N はブロック数ではなく、バイト数と見なされる。

seek=N
     出力ファイルで obs バイトのブロックを N 個スキップしてから、コピーを行う。oflag=seek_bytes が指定されている場合は、 N はブロック数ではなく、バイト数と見なされる。

count=N
     入力ファイルの末尾まで全部ではなく、ibs バイトのブロックを N 個だけ入力ファイルからコピーする。iflag=count_bytes が指定されている場合は、N はブロック数ではなく、バイト数と見なされる。なお、次のことに注意してほしい。パイプから読み込んでいる場合などに時おり起きることだが、入力からの読み込みがブロックの大きさに足りないことがある。そうした場合に iflag=fullblock が指定してあると、count= は、一杯になるまで読み込むブロックの個数を意味するようになる。入力から読み込みを実行する回数という POSIX で規定されている伝統的な動作ではなくなるのだ。

status=LEVEL
     通常では INFO シグナルを受け取った時点や、dd が終了したときに、転送情報が標準エラーに出力される。 LEVEL の指定によって、表示する情報の量を調節することができる。指定された LEVEL のうち、最後のものが優先される。

     none
          情報メッセージや警告メッセージを標準エラーに全く表示しない。エラーメッセージは通常どおり出力する。

     noxfer
          最終的な転送速度や転送量の統計を表示しない。通常は、そうした情報がステータス表示の最後の行になる。

     progress
          各入力ブロックを処理するとき、転送速度と転送量の統計を標準エラーに表示する。転送量の統計は 1 行に表示され、最も頻繁な場合、1 秒ごとに出力されるが、 I/O 待ちが起きると、更新が遅れることがある。

conv=CONVERSION[,CONVERSION]...
     CONVERSION 引数 (複数可) で指定されたようにファイルを変換する。 (コンマの前後にスペースを入れてはいけない。)

     CONVERSION には次のものが指定できる:

     ascii
          POSIX が規定している変換テーブルを使って、EBCDIC を ASCII に変換する。変換テーブル中の 256 バイトのすべてについて、1 対 1 の変換が行われる。このオプションを指定すると、conv=unblock も指定されることになる。入力はまず ASCII に変換され、その後で末尾のスペースが除去される。

     ebcdic
          ASCII を EBCDIC に変換する。これは ascii 変換の逆の動作である。このオプションを指定すると、conv=block も指定されることになる。末尾にスペースが追加されてから、EBCDIC に変換される。

     ibm
          この指定の動作は conv=ebcdic に似ている。ただし、POSIX が規定しているもう一つの変換テーブルを使って、変換する点が違う。こちらは 1 対 1 の変換ではないが、~, [, ] について、よく使われる伝統的な慣行を反映している。

          ascii, ebcdic, ibm は、どれか一つしか指定できない。こうしたオプションの一つを使う場合は、cbs= も指定すべきである。

     block
          入力 1 行あたり、cbs バイトを出力する。入力中の改行はスペースに置き換え、cbs バイトに足りない分はスペースで埋める。

     unblock
          cbs バイトの大きさからなる各入力ブロックに対して、末尾にスペースがあれば、それをすべて削除し、改行を追加する。

          block と unblock は、どちらか一方しか指定できない。

     lcase
          大文字を小文字に変換する。

     ucase
          小文字を大文字に変換する。

          lcase と ucase は、どちらか一方しか指定できない。

     sparse
          出力ブロックが NUL のみからなっているとき、それを書き出さずに、seek を試みる。穴空きファイル (sparse file) をサポートしているシステムでは、この動作は、出力ファイルを書き出しているときに、穴空きの出力を作成することになる。このオプションを conv=notrunc や oflag=append と一緒に使う際は、気をつけなければならない。conv=notrunc が付いていると、入力中の NUL ブロックに対応する位置にある、出力ファイル中の存在するデータは、そのまま保持されることになる。oflag=append を付けた場合は、 seek は行っても効果がない。なお、conv=sparse では、出力先がファイルではなく、デバイスの場合も、入力中の NUL ブロックはやはりコピーされない。そんなわけで、このオプションが最も役に立つのは、仮想デバイスや、前もって 0 で初期化したデバイスに対してである。

     swab
          入力された全バイトを 2 個づつ組にして、前後を入れ替える。GNU の dd は、他の dd とは違って、読み込むバイトが奇数個でも動作する。最後のバイトは （入れ替えるものがないので) そのままコピーするのである。

     sync
          すべての入力ブロックに対して ibs の大きさになるまで、末尾をゼロバイトで埋める。 block や unblock と一緒に使用すると、ゼロバイトの代わりにスペースで埋める。

     以下の CONVERSION は、実のところファイルの扱いに関するフラグなので、内的な処理には影響を及ぼさない。

     excl
          出力ファイルがすでに存在する場合は、実行に失敗する。言い換えれば、dd が出力ファイルを自分で作成しなければならないということである。

     nocreat
          出力ファイルを作成しない。言い換えれば、出力ファイルは前もって存在していなければならないということだ。

          excl と nocreat は、どちらか一方しか指定できない。

     notrunc
          出力ファイルに対して短縮操作をしない (訳注: of=FILE の項を参照)。

     noerror
          読み込みエラーがあっても、作業を続行する。

     fdatasync
          コマンドを終了する直前に、出力データを同期させる。すなわち、出力データをディスクに実際に書き込む。

     fsync
          コマンドを終了する直前に、出力データだけでなく、メタデータも同期させる。すなわち、出力データとメタデータをディスクに実際に書き込む。

iflag=FLAG[,FLAG]...
     引数 FLAG によって指定されたフラグを使って、入力ファイルにアクセスする。 (コンマの前後にスペースを入れてはいけない。)

oflag=FLAG[,FLAG]...
     引数 FLAG によって指定されたフラグを使って、出力ファイルにアクセスする。 (コンマの前後にスペースを入れてはいけない。)

     フラグには次のものがある。どのオペレーティング・システムでも、すべてのフラグが使えるわけではない。

     append
          追加モードで書き込む。従って、何か別のプロセスが問題のファイルに書き出している場合でも、 dd の書き込みは、書き込むたびに、そのファイルの今現在の内容に追加されることになる。このフラグは出力に対してしか意味がない。なお、このフラグを of=FILE オペランドと組み合わせて使うのなら、 conv=notrunc も一緒に指定した方がよい。さもないと、出力ファイルは、追加書き込みが始まる前に、短縮操作を受けることになる。

     cio
          データに対してコンカレント I/O (CIO) モードを使用する。このモードでは、ダイレクト I/O を行いつつ、同じファイルに対するすべての I/O は順番に行わなければならないという POSIX の要件は無視する。一つのファイルを CIO モードと標準的な方法の両方で同時にオープンすることはできない。

     direct
          データに対してダイレクト I/O を使用し、バッファ・キャッシュを介さないようにする。カーネルが read バッファや write バッファのサイズに制限をかけていることがあるのに注意していただきたい。たとえば、出力先のファイルシステムが ext4 で、カーネルが linux ベースの場合、出力バッファのサイズが 512 の倍数でなければ、oflag=direct を指定すると、EINVAL で書き込みに失敗することになる。

     directory

          ファイルがディレクトリでなければ、実行に失敗する。ほとんどのオペレーティング・システムがディレクトリに対する I/O を許していない。従って、このフラグが役に立つ機会はめったにない。

     dsync
          データに対して同期 I/O を使用する。出力ファイルについては、このフラグは、各書き込みごとに出力データをディスクに実際に書き込ませる。入力ファイルについてこのフラグが意味を持つかもしれないのは、読み込んでいるのがリモートのファイルであり、それが何か他のプロセスによって同期的に書き込まれているときである。メタデータ (たとえば、最終アクセス日時や最終更新日時) は、必ずしも同期されない。

     sync
          データとメタデータに対して同期された I/O を使用する。

     nocache
          システムの持つファイルのデータ・キャッシュを廃棄するよう要求する。 count=0 の場合は、ファイルのキャッシュされたデータ全体を指定することになる。それ以外の場合は、ファイルのキャッシュのうち、処理の対象になった部分だけが捨てられる。また、count=0 のとき、キャッシュの廃棄に失敗すると、その旨メッセージが表示され、終了ステータスに反映する。

          念のために言っておくと、ストレージへの書き込みがまだ終了していないデータが、キャッシュから捨てられることはない。そこで、下記の用例で ``sync'' オプションを使っていることに注目していただきたい。 nocache フラグの効率を最大にするために使用しているのである。

          用例をいくつか挙げておく。

               # ファイル全体のキャッシュを捨てるように指示する。
               dd if=ifile iflag=nocache count=0

               # ファイル全体のキャッシュを確実に捨てる。
               dd of=ofile oflag=nocache conv=notrunc,fdatasync count=0

               # ファイル中の一部分のキャッシュを捨てる。
               dd if=ifile iflag=nocache skip=10 count=10 of=/dev/null

               # read-ahead キャッシュのみを使って、データを転送する。
               # direct フラグの項も参照すること。
               dd if=ifile of=ofile iflag=nocache oflag=nocache,sync

     nonblock
          ノンブロッキング I/O を使用する。

     noatime
          ファイルのアクセス日時を更新しない。古いシステムの中には、エラーや警告も出さずに、このフラグを無視するものがある。そこで、このフラグを使用する前に、有効かどうか、お手元のファイルで試してみるとよい。

     noctty
          入力 (または、出力) ファイルを dd の制御端末にしない。このフラグは、そのファイルが端末でなければ、効果がない。このフラグが全く効果を持たないホストが、たくさんある (たとえば、GNU/Linux ホストがそうである)。

     nofollow
          シンボリックリンクをたどらない。

     nolinks
          ファイルに複数のハードリンクがあれば、実行に失敗する。

     binary
          バイナリ I/O を使用する。このフラグは、バイナリ I/O とテキスト I/O を区別する非標準的なプラットフォームでしか効果がない。

     text
          テキスト I/O を使用する。このフラグが標準的なプラットフォームで効果がないのは、 binary と同様である。

     fullblock
          各ブロックが一杯になるまで入力から読み込む。read システムコールは、入力がブロックの分量に足りない場合、早めに戻ってくることがある。そうした場合に、read の呼び出しを繰り返して、ブロックの残りを埋めようとする。このフラグは、iflag でのみ使用できる。このフラグが役に立つのは、たとえばパイプと組み合わせて使うときである。パイプとの組み合わせでは、入力からの読み込みがブロックの大きさに足りないことがあるからだ。そうした場合に、count= の引数が、読み込み動作の回数ではなく、読み込むブロック数だと確実に解釈されるようにするには、このフラグが必要になる。

     count_bytes
          count= オペランドをブロック数ではなく、バイト数の指定と見なす。そうすることで、I/O ブロックサイズの倍数ではない長さが、指定できるようになるわけだ。このフラグは iflag でしか使用できない。

     skip_bytes
          skip= オペランドをブロック数ではなく、バイト数の指定と見なす。そうすることで、I/O ブロックサイズの倍数ではないオフセットが、指定できるようになるわけだ。このフラグは iflag でしか使用できない。

     seek_bytes
          seek= オペランドをブロック数ではなく、バイト数の指定と見なす。そうすることで、I/O ブロックサイズの倍数ではないオフセットが、指定できるようになるわけだ。このフラグは oflag でしか使用できない。

     以上のフラグは、すべてのシステムでサポートされているわけではなく、サポートされていないシステムで使用しようとすると、dd に拒否される。標準入力から読み込んでいる場合や、標準出力に書き出している場合は、 nofollow や noctty フラグは指定するべきではない。また、他のフラグ (たとえば nonblock) は、対象となるファイルのファイル・ディスクリプタに対する他のプロセスの動作に、dd が終了した後までも、影響を及ぼすかもしれない。

上記中の数値を表す文字列  (N や BYTES) には、乗数を示す文字を後ろに付けることができる。すなわち、b=512, c=1, w=2, xM=M といった文字である (訳注: 最後のものは、10xM という表記は 10M と書くのと同じだということ)。あるいは、k=1024 のような、ブロックサイズに付ける標準の接尾辞の一つを続けてもよい (see Block size)。

bs=, ibs=, obs=, "cbs= を使って指定するブロックサイズは、大きすぎない方がよい。数メガバイトを越える値は、一般的に言って無駄だし、 (ギガバイト ... エクサバイトを使ったときのように) 全く逆効果だったり、エラーの元になったりする。

データのオフセット位置やサイズが I/O ブロックサイズの倍数ではない場合に、そうしたデータを処理するには、skip_bytes, seek_bytes, count_bytes といったフラグを使用すればよい。あるいは、dd を別々に呼び出すという伝統的な手法を使用することもできる。一例を挙げると、以下のシェルコマンドは、1 ブロック を 512 KiB にして、ディスクとテープの間でデータをコピーしている。ただし、ディスクの先頭にある 4 KiB のラベルについては、保存も復元も行っていない。

     disk=/dev/rdsk/c0t1d0s2
     tape=/dev/rmt/0

     # ラベル以外のすべてをディスクからテープへコピーする。
     (dd bs=4k skip=1 count=0 && dd bs=512k) <$disk >$tape

     # テープからディスクへ書き戻す。ただし、ディスクのラベルには手を
     # 付けない。
     (dd bs=4k seek=1 count=0 && dd bs=512k) <$tape >$disk

壊れかけたディスクについては、様々なおまけ機能が付いたツールが他にあり、そうしたものを使えば、ディスクが本当にダメになってしまう前に、できるだけ多くのデータを救済することが容易になる。たとえば、GNU ddrescue がその一つだ (http://www.gnu.org/software/ddrescue/)。しかしながら、場合によっては、そうしたツールが使えないこともあるし、管理者にとって dd を操作する方が安心できるということもある。そうした場合は、簡単なレスキュー方法として、dd を以下の例で示すように実行すればよい。 conv=noerror,sync オプションを使っているのは、リードエラーがあっても続行し、読み込めなかった部分 (bad read) を NUL で埋めるためである。また、iflag=fullblock は、ショートリードに対する用心だ (そうしたことが磁気ディスクを使っているデバイスで起きたことは、これまでにないけれど)。

     # 壊れかけたディスクのパーティションから (マウントしていない
     # パーティションだ！) データを救済する。
     dd conv=noerror,sync iflag=fullblock </dev/sda1 > /mnt/rescue.img

実行中の dd のプロセスに INFO シグナルを送ると (それが使えないシステムでは、USR1 シグナルを送る)、 dd は入出力の統計情報を標準エラーに書き出し、それからコピー作業を続行する。以下の例では、dd をバックグラウンドで実行し 5GB のデータのコピーを行っている。kill コマンドが実行されると、 dd は実行途中の入出力統計を表示する。そして、正常に作業を完了するか、SIGINT シグナルによって中断されたとき、最終的な統計情報を出力する。

     # シェルが子プロセスである dd をうっかり終了させてしまうことが
     # 絶対にないように、USR1 シグナルを「無視する」にしておく。
     # なお、SIGINFO が利用できる場合は、これをやる必要はない。
     trap '' USR1

     # シグナルを受けることが引き鉄になって、ショートリードが起きるかも
     # しれない。それを避けるために、dd を iflag=fullblock で実行する。
     dd iflag=fullblock if=/dev/zero of=/dev/null count=5000000 bs=1000 & pid=$!

     # 1 秒ごとに統計情報を出力する。
     while kill -s USR1 $pid 2>/dev/null; do sleep 1; done

上記のスクリプトの出力は、次のようなフォーマットになる。

     3441325+0 records in
     3441325+0 records out
     3441325000 bytes (3.4 GB, 3.2 GiB) copied, 1.00036 s, 3.4 GB/s
     5000000+0 records in
     5000000+0 records out
     5000000000 bytes (5.0 GB, 4.7 GiB) copied, 1.44433 s, 3.5 GB/s

status=progress オプションを付けると、転送統計を表す上記の最後の行が定期的に更新される。

INFO シグナルが存在しないシステムでは、 環境変数 POSIXLY_CORRECT が設定されていないかぎり、dd は INFO の代わりに USR1 に反応する。

終了ステータス 0 は成功を示し、0 以外の値は失敗を示す。

install: ファイルをコピーし属性をセットする
==========================

install はファイルをコピーするとき、ファイルのモードビット (訳注: 一般にアクセス権とか、許可属性と言われるもの) をセットし、可能ならば、所有者やグループも設定する。

書式:

     install [OPTION]... [-T] SOURCE DEST
     install [OPTION]... SOURCE... DIRECTORY
     install [OPTION]... -t DIRECTORY SOURCE...
     install [OPTION]... -d DIRECTORY...

  * ファイル名を二つ指定すると、install は最初のファイルを 2 番目のファイルにコピーする。

  * --target-directory (-t) オプションを指定した場合や、あるいはそれを指定しないでも、最後のファイルがディレクトリであり、しかも --no-target-directory (-T) オプションを指定していない場合は、 install は各 SOURCE ファイルを指定されたディレクトリに、SOURCE の名前でコピーする。

  * --directory (-d) を指定すると、install は各 DIRECTORY を作成する。このとき、親ディレクトリが存在しなければ、それも作成する。作成される親ディレクトリのモードは、-m オプションの指定や現在の umask にかかわりなく、u=rwx,go=rx (755) になる。親ディレクトリの set-user-ID ビットや set-group-ID ビットの継承については、次の節を参照していただきたい。See Directory Setuid and Setgid.

install は cp に似ているが、コピー先ファイルの属性を自由に設定できる点が違う。 install は通常、Makefile の中で、プログラムを目標のディレクトリにコピーするために使用される。 install では、ファイルをそれ自身にコピーすることはできない。

install が拡張属性 (xattr) を保存することはない。

このプログラムでは以下のオプションが使用できる。参照: Common options.

-b
--backup[=METHOD]
     See Backup options.  そのままでは、上書きされるか、消去されてしまう各ファイルのバックアップを作成する。

-C
--compare
     インストール元とインストール先の対応するファイルを比較し、インストール先にあるファイルがインストール元と内容が同じで、しかも、所有者、グループ、許可属性、場合によっては SELinux コンテキストについて、そのどれもが指定されているものと同一であるときは、インストール先ファイルを全く変更しない。このオプションは、--user, --group, --mode オプションと併せて使うのが最善である。そういうものを指定しない場合、 install コマンドが、(たとえば、ディレクトリに setgid が付いていることや、POSIX のデフォルトの ACL を顧慮しないせいで)、インストールされるファイルがデフォルトで持つはずの属性を不正確に決めてしまうかもしれないのだ。そんなことがあると、無駄なコピーが行われたり、属性が正しいデフォルト値に設定されなかったりといった不都合が生じかねない。

-c
     無視する。Unix の古いバージョンの  install との互換性のためにある。

-D
     DEST の指定中に存在していない親ディレクトリがあれば、それを作成してから、SOURCE を DEST にコピーする。 -D とともに明示的に --target-directory=DIR を指定した場合も、やはり出力先のディレクトリ階層が確実に存在するようになる。

-d
--directory
     まず、存在していない親ディレクトリがあれば作成し、それにデフォルトの属性を与える。それから、指定された各ディレクトリを作成し、所有者、グループ、許可属性を、コマンドラインで指定されたとおりに、またはデフォルトの値に設定する。

-g GROUP
--group=GROUP
     インストールするファイルやディレクトリの所有グループを GROUP にする。デフォルトでは、プロセスの現在のグループになる。 GROUP は、グループ名でも、グループの ID 番号でもよい。

-m MODE
--mode=MODE
     インストールするファイルやディレクトリのモードビットを MODE にする。 MODE の指定は、a= (誰にもアクセスを許さない) を基点として行い、 8 進数でも、chmod で使うようなシンボリックモードでもよい (see File permissions)。デフォルトのモードは、 u=rwx,go=rx,a-s である。すなわち、所有者には読み、書き、実行を許可し、グループとその他のユーザには読みと実行のみを許可、 set-user-ID と set-group-ID は無効にする。このデフォルトは、755 と全く同じではない。なぜなら、デフォルトの方は、ディレクトリについて set-user-ID や set-group-ID を引き継がず、無効にしているからである。 See Directory Setuid and Setgid.

-o OWNER
--owner=OWNER
     install が適切な権限を持っている場合に (つまり、root 権限で実行されている場合に)、インストールするファイルやディレクトリの所有者を OWNER にする。デフォルトでは root になる。OWNER の指定は、ユーザ名でも、ユーザの ID 番号でもよい。

--preserve-context
     ファイルやディレクトリの SElinux セキュリティ・コンテキストを引き継ぐ。ファイルやディレクトリすべてのセキュリティ・コンテキストを引き継げなかった場合は、終了ステータスが 1 になる。SElinux が無効になっているときは、警告を出し、このオプションを無視する。

-p
--preserve-timestamps
     インストール先各ファイルの最終アクセス日時 (last access time) と最終更新日時 (last modification time) を、対応するインストール元各ファイルのそれぞれの日時に合わせる。このオプションを付けずにインストールした場合、各ファイルの最終アクセス日時と最終更新日時は、両方ともインストールした日時になる。インストール先ファイルの最終更新日時を、最後にインストールした日付ではなく、最後にビルドした日付の記録として使用したい場合、このオプションは便利である。

-s
--strip
     インストールされるバイナリの実行ファイルからシンボル・テーブルを取り除く。

--strip-program=PROGRAM
     バイナリからシンボル・テーブルを取り除くために使用するプログラムを指定する。

-S SUFFIX
--suffix=SUFFIX
     -b によって作られる各バックアップファイルの後ろに SUFFIX を付ける。 See Backup options.

     -D オプションも指定すると、
     ディレクトリの存在が保証される。

-T
--no-target-directory
     最後のオペランドがディレクトリやディレクトリへのシンボリックリンクでも、それを特別扱いしない。 See Target directory.

-v
--verbose
     コピーを行う前に、コピーするファイル名を表示する。

     このオプションと --preserve-context
     オプションは、どちらか一方しか指定できない。 (CONTEXT を省略できるのは、coreutils-8.22 から)

終了ステータス 0 は成功を示し、0 以外の値は失敗を示す。

mv: ファイルの移動 (名前の変更) を行う
=======================

mv は、ファイル (やディレクトリ) の移動、または名前の変更を行う。

書式:

     mv [OPTION]... [-T] SOURCE DEST
     mv [OPTION]... SOURCE... DIRECTORY
     mv [OPTION]... -t DIRECTORY SOURCE...

  * ファイル名を二つ指定すると、mv は最初のファイルを 2 番目のファイルに移動する。

  * --target-directory (-t) オプションを指定した場合や、あるいはそれを指定しないでも、最後のファイルがディレクトリであり、しかも --no-target-directory (-T) オプションを指定していない場合は、 mv は各 SOURCE ファイルを指定されたディレクトリに、SOURCE の名前で移動する。

mv はいかなるタイプのファイルでも、一つのファイルシステムから別のファイルシステムへ移動させることができる。 fileutils パッケージのバージョン 4.0 以前では、mv がファイルシステム間を移動させることができたのは、通常ファイルだけだった。それに対して、現在の mv では、たとえば、スペシャル・デバイスファイルを含むディレクトリ階層の全体を、あるパーティションから別のパーティションへ移動させることが可能になっている。 mv は、まず cp -a が使用するのと同じコードを使って、指定されたディレクトリやファイルをコピーし、その後で (コピーに成功した場合は) コピー元を削除する。コピーに失敗した場合は、移動先のパーティションにすでにコピーした部分を消去することになる。仮に、あるパーティションから別のパーティションに、3 個のディレクトリをコピーしようとして、最初のディレクトリのコピーには成功したものの、2 番目のディレクトリのコピーに失敗したとしよう。その場合、最初のディレクトリは、移動先のパーティションに残るが、2 番目と 3 番目のディレクトリは、元のパーティションに残ることになる。

mv は拡張属性 (xattr) を常にコピーしようとする。この拡張属性は、SELinux コンテキストや ACL、ケーパビリティであってもよい。拡張属性のコピーに失敗したときは、Operation not supported 以外のすべての警告が出力される。

移動先ファイルがすでに存在し、それが普通なら書き込みのできないものである場合、標準入力が端末であり、-f や --force オプションが指定されていなければ、 mv はプロンプトを出して、ファイルを置き換えるかどうか、ユーザに問い合わせる (ファイルの書き込み権限がなくても、自分がそのファイルの所有者であったり、そのディレクトリの書き込み権限を持っていたりすることは、ありえることである)。答えが肯定でなければ、そのファイルはスキップされる。

警告: 名前変更の対象 (または、移動元) がディレクトリへのシンボリックリンクかもしれないときは、その名前を指定する際に、末尾にスラッシュを付けてはいけない。さもないと、mv の動作は内部で使っている rename システムコール次第なので、全く予想外のことが起きるかもしれないのだ。 Linux ベースの最近のカーネルを使っているシステムでは、errno=ENOTDIR で実行に失敗する。しかし、他のシステムでは (少なくとも、FreeBSD 6.1 や Solaris 10 では)、シンボリックリンクではなく、リンクが参照しているディレクトリの名前の方を、警告なしで変更するのである。 See Trailing slashes.

注意: mv が移動先にあるディレクトリを置き換えるのは、そのディレクトリが空のときだけである。移動先にある名前の衝突する (訳注: 要するに移動元ディレクトリと同名の) ディレクトリにファイルがあるときは、「ディレクトリが空ではない」旨のメッセージを出して、そのディレクトリをスキップする。

このプログラムでは以下のオプションが使用できる。参照: Common options.

-b
--backup[=METHOD]
     See Backup options.  そのままでは、上書きされるか、消去されてしまう各ファイルのバックアップを作成する。

-f
--force
     移動先のファイルを消去する前に、プロンプトを出してユーザに問い合わせることをしない。
     -i, -f, -n オプションを同時に指定している場合は、
     最後に指定したもののみが効果を持つ。

-i
--interactive
     ファイルの許可属性に関係なく、存在する各移動先ファイルを上書きするかどうかを、プロンプトを出してユーザに問い合わせる。答えが肯定でなければ、そのファイルをスキップする。-i, -f, -n オプションを同時に指定している場合は、
     最後に指定したもののみが効果を持つ。

-n
--no-clobber
     存在するファイルを上書きしない。-i, -f, -n オプションを同時に指定している場合は、
     最後に指定したもののみが効果を持つ。このオプションは、-b や --backup オプションと一緒には使えない。

-u
--update
     ディレクトリ以外のものを移動する際、それが移動先にも存在し、しかもその更新日時 (modification time) が移動元と同じか、より新しい場合には、移動を行わない。移動が別のファイルシステムに向かって行われる場合、タイムスタンプの比較は、移動元のタイムスタンプを移動先のファイルシステム、及びタイムスタンプの更新に使われるシステムコールの精度に落とした上で行われる。これは、同じ移動元と移動先に対して、mv -u コマンドが何回か実行される場合に、コピー作業が繰り返されるのを避けるためである。

-v
--verbose
     移動する前に各ファイルの名前を表示する。

--strip-trailing-slashes
     SOURCE 引数の後ろにスラッシュが付いていたら、それを削除する。 See Trailing slashes.

-S SUFFIX
--suffix=SUFFIX
     -b によって作られる各バックアップファイルの後ろに SUFFIX を付ける。 See Backup options.

-t DIRECTORY
--target-directory=DIRECTORY
     DIRECTORY を出力先ディレクトリに指定する。 See Target directory.

-T
--no-target-directory
     最後のオペランドがディレクトリやディレクトリへのシンボリックリンクでも、それを特別扱いしない。 See Target directory.

-Z
--context
     このオプションは restorecon と似た働きをする。すなわち、移動先における SELinux セキュリティ・コンテキストを、移動先のファイルやそこに作られる各ディレクトリに対する、システムのデフォルトのタイプに合わせて調整する。

終了ステータス 0 は成功を示し、0 以外の値は失敗を示す。

rm: ファイルやディレクトリを削除する
====================

rm は、指定された各ファイルを削除する。デフォルトでは、ディレクトリの削除は行わない。

書式:

     rm [OPTION]... [FILE]...

-I または --interactive=once オプションが指定されている場合に、削除するファイルが 4 個以上あるか、あるいは -r, -R, --recursive などのオプションが指定されていると、rm はプロンプトを出して、作業を最後まで行うかどうか、ユーザに問い合わせる。答えが肯定でなければ、コマンド全体が中止になる。

それ以外の場合でも、削除するファイルが書き込み不可で、標準入力が端末、しかも --force (-f) オプションが指定されていない場合や、-i または --interactive=always オプションが指定されている場合には、rm はプロンプトを出して、そのファイルを削除するかどうか、ユーザに問い合わせる。答えが肯定でなければ、そのファイルをスキップする。

ファイル名の最後の構成要素 (訳注: ファイル名 (いわゆるパス名) の最後の / より後ろの部分) が . や .. であるファイルを削除しようとしても、rm はそれを実行せず、ユーザに問い合わせることもない。これは POSIX が要求している動作である。

警告: rm を使って、ファイルを削除しても、たいていの場合、そのファイルの内容を復元することが可能である。ファイルの内容が間違いなく復元不可能であるとの、より一層の保証が欲しいのなら、 shred コマンドの使用をお考えになるとよい。

このプログラムでは以下のオプションが使用できる。参照: Common options.

-d
--dir
     指定されたディレクトリが空ならば、それを削除する。

-f
--force
     指定したファイルが存在しなかったり、削除の対象を一つも指定しなかったりしても、問題にしない (訳注: 言い換えれば、エラーにならない)。また、ユーザに対する問い合わせも全く行わない。 --interactive (-i) オプションが前にあっても、それを無視する。

-i
     プロンプトを出して、各ファイルを削除するかどうか、ユーザに問い合わせる。答えが肯定でなければ、そのファイルをスキップする。 --force (-f) オプションが前にあっても、それを無視する。

-I
     4 個以上のファイルが指定された場合や、再帰的な削除が要求された場合に、プロンプトを出して、コマンドを続行するかどうか、ユーザに一度だけ尋ねる。 --force (-f) オプションが前にあっても、それを無視する。 --interactive=once と同じである。

--interactive [=WHEN]
     問い合わせのプロンプトをいつ出すかを指定する。WHEN には以下の一つを指定できるが、なくてもよい。

       * never - 問い合わせを全くしない。

       * once - 4 個以上のファイルが指定された場合や、再帰的な削除が要求された場合に、一度だけ問い合わせをする。-I と同じ。

       * always - 削除されるすべてのファイルに対して問い合わせをする。-i と同じ。

     --interactive に WHEN を指定しないのは、--interactive=always と同じである。

--one-file-system
     ディレクトリ階層を再帰的に削除する際に、コマンドラインで引数として指定したディレクトリが存在するファイルシステムとは別のファイルシステム上にある、いかなるディレクトリも削除しない。

     このオプションが役に立つのは、ビルド用の ``chroot'' ディレクトリ階層を削除する場合である。通常、そうしたディレクトリ階層に重要なデータは含まれていない。しかしながら、普段使っているスタートアップ・ファイルを利用しやすくするために、そうしたディレクトリ階層に /home を bind-mount するのは、珍しいことではない。問題は、/home のアンマウントを忘れやすいことである。アンマウントをやり忘れたまま、rm -rf を使って、通常使い捨てにする chroot 環境を削除しようとすると、/home 以下にあるすべてまで削除してしまうことになる。 --one-file-system オプションを使えば、rm は警告を出した上で、他のファイルシステムにあるディレクトリをスキップしてくれる。当然ながら、/home と chroot 環境が同じファイルシステムにある場合は、このオプションを使っても、/home が助かるわけではない。

--preserve-root
     --recursive オプションと一緒に使った場合、ルートディレクトリ (/) を削除しようとした時点で、実行に失敗する。これがデフォルトの動作である。 See Treating / specially.

     (訳注: 確かに --preserve-root が有効になっていれば、rm -rf / とした場合に、ルートディレクトリが保護されることになる。だが、rm -rf /* とした場合には、あまり役に立たない。なぜなら、/* は、/bin, /usr, /home などに展開されるが、そうしたディレクトリの消去は、--preserve-root によっては止められないからである。)

--no-preserve-root
     再帰的に削除を行う際、/ を特別扱いしない。コンピュータ上にあるすべてのファイルを本当に削除したい場合以外、このオプションの使用はお勧めできない。 See Treating / specially.

-r
-R
--recursive
     コマンドラインにリストされたディレクトリとその中身を再帰的に削除する。

-v
--verbose
     削除を行う前に、各ファイルの名前を表示する。

よくある質問の一つに、名前が - で始まるファイルを削除するには、どうしたらよいか、というものがある。GNU の rm では、getopt を使用して引数の解析を行っているあらゆるプログラムと同様、-- オプションを使って、以下の引数はすべてオプションではない、と示すことが可能になっている。カレントディレクトリにある -f というファイルを削除するには、次のどちらかをタイプすればよい。

     rm -- -f

あるいは、

     rm ./-f

Unix の rm プログラムが、この用途に - を 1 個だけ使っていたのは、 getopt の標準シンタックスが開発される以前のことである。

終了ステータス 0 は成功を示し、0 以外の値は失敗を示す。

shred: セキュリティを向上させたファイルの削除
==========================

shred はデバイスやファイルを上書きして、非常に高価な装置を使用しても、データの復元ができないようにする。

通常、ファイルを削除しても (see rm invocation)、データが実際に消去されるわけではない。単に、ファイルが格納されている場所をリストしたインデックスが破棄されるだけであり、そうすることで、そのデータの格納場所が再利用可能になるのである。世の中には、インデックスの再構築を試みる復元ソフト (undelete utilities) というものが存在する。そうしたものは、ファイルの存在したスペースが再利用されていなければ、ファイルを復元することができるのだ。

頻繁に使われているシステムで、ディスクがほとんど一杯になっている場合、スペースは数秒のうちに再利用されるかもしれない。だが、それを確実に知る方法は全くない。また、他人に見られては困るデータがあったところで、見られても構わないデータでそのファイルを上書きしてしまえば、復元は絶対不可能だと考えたいかもしれない。

しかしながら、そういうことをした後でも、ディスクを研究所に持ち込んで、高感度の (そして高価な) 装置を山ほど使用すれば、上書きされたデータの下にある元のデータのかすかな「痕跡 (echoes)」を検出することが可能なのだ。もし、データがたった一回しか上書きされていなかったら、それはさほど難しいことでもない。

データを復元できないように消去する最善の方法は、それが載っているメディアを酸で破壊するとか、熱で溶かすとかすることである。フロッピーディスクのような廉価なリムーバブル・メディアの場合、それがよく使われる方法だ。だが、ハードディスクは高価だし、熱で溶かすのも難しい。そこで、shred ユーティリティは、物質的な破壊以外の方法で、同様の効果を実現しようとするのである。

そのためには、元のデータに与える損傷を最大にするように選ばれたデータパターンで繰り返し上書きするという方法が採られる。この方法は、フロッピーディスクにも効果があるものの、パターンはハードディスクで最も効果を上げるように工夫されたものだ。詳細については、ソースコードや、第 6 回 USENIX セキュリティ・シンポジウム (San Jose, California, July 22--25, 1996) の議事録にある Peter Gutmann の次の論文をご覧になっていただきたい。

Secure Deletion of Data from Magnetic and Solid-State Memory (http://www.cs.auckland.ac.nz/~pgut001/pubs/secure_del.html)

ここで心に銘記してしていただきたいのは、shred には非常に重要な前提があるということである。すなわち、ファイルシステムはデータを、それが存在する場所で上書きするものでなければならない。それは、こうした操作を行うときの伝統的な方法であるが、最近のファイルシステムの設計には、この前提を満たさないものが多い。そうした例外には、次のようなものがある。

  * ログ構造化 (log-structured) ファイルシステムや、ジャーナル化 (journaled) ファイルシステム。たとえば、ATX や Solaris で提供されているもの。JFS, ReiserFS, XFS, Ext3 (data=journal モードの場合), BFS, NTFS などが、「データ」のジャーナリングをするように設定されている場合もこれに当たる。

  * データを冗長化して書き込んだり、一部の書き込みに失敗することがあっても、動作し続けるファイルシステム。たとえば、RAID ベースのファイルシステム。

  * Network Appliance の NFS サーバのように、スナップショットを作成するファイルシステム。

  * NFS バージョン 3 のクライアントのように、一時領域にキャッシュを作るファイルシステム。

  * 圧縮ファイルシステム。

特に ext3 ファイルシステムについて言うと、上記の例外に当てはまるのは (その結果、shred が限定された効果しか持たないのは)、data=journal モードの場合だけである。これは、メタデータだけでなく、ファイルデータもジャーナリングするモードだ。data=ordered (デフォルト) と data=writeback の両モードでは、shred は通常どおり役に立つ。 ext3 のジャーナリング・モードを変更するには、mount のマニュアルに書いてあるように (man mount)、/etc/fstab ファイルで問題のファイルシステムのマウントオプションに data=something オプションを追加すればよい。

ファイルシステムがどういう動作をしているか、よくわからない場合は、データをそれが存在する場所で上書きしていないと考えておいた方がよい。すなわち、そのファイルシステムでは、通常ファイルに対する shred の動作は、信頼できないということである。

一般的に言って、shred は、ファイルよりデバイスに対して使った方が信頼できる。そうすれば、上に述べたファイルシステムの設計の問題を回避できるからだ。しかしながら、shred のデバイスに対する使用も、必ずしも全面的に信頼できるわけではない。たとえば、ほとんどのディスクが、バッドセクターを使用に割り当てる領域から外して、アプリケーションから見えないようにしている。そこで、バッドセクターに他人に見られたくないデータがある場合、shred はそれを破壊できないことになる。

shred は、バックアップに対して何の対処も行おうとしないが、バッドセクターの問題についても全く同様で、検知しようともしないし、通知しようともしない。それでも、shred はファイルに対して行うより、デバイスに対して行う方が信頼できるので、デフォルトでは、出力ファイルをサイズ 0 に短縮したり、削除したりしないようになっている。このデフォルトは、ファイルよりデバイスに適した動作だ。デバイスは一般に短縮できないし、削除するべきでもないからである。

最後になったが、バックアップやミラーの持つリスクも考慮した方がよい。削除することのできないファイルのコピーが、ファイルシステムのバックアップやリモートのミラーに残っているかもしれないのだ。そして、そうしたものが残っていれば、shred で破壊したファイルを後日復元することが可能になる。だから、後で shred を使って破棄したくなりそうなデータがある場合には、そのバックアップやミラーがないことを確認すべきなのである。

     shred [OPTION]... FILE[...]

このプログラムでは以下のオプションが使用できる。参照: Common options.

-f
--force
     必要ならば、ファイルの許可属性を無視して、上書きできるようにする。

-n NUMBER
--iterations=NUMBER
     デフォルトで shred は、上書きを SHRED_DEFAULT_PASSES 回する。時間を節約するために、回数を減らすこともできるし、その方がよいと思えば、回数を増やすこともできる。 25 回上書きすると、プログラムが内部に持っている上書き用のパターンのすべてが、少なくとも一回は使われたことになる。

--random-source=FILE
     上書きに使用するランダムデータのソースとして FILE を使用する。また、このランダムデータは、上書きパターンの順番を決めるのにも使用される。

-s BYTES
--size=BYTES
     ファイルの最初の BYTES バイトを shred 処理する。デフォルトは、ファイル全体の shred である。BYTES の後ろには、その何倍かを示すために K, M, G といった、サイズの指定を付けることができる。 See Block size.

-u
--remove[=HOW]
     shred 処理したファイルを (可能ならば) サイズ 0 に短縮し (truncate)、その上で削除する。ファイルが複数のリンクを持っている場合に、削除されるのは名前を指定されたリンクだけである。ファイルの名前は、ファイルの内容ほど秘密性を必要としないことも多い。そうした場合は、長い書式のオプションでサポートされている HOW パラメータを付けることで、各ディレクトリエントリのより効率的な削除法を指定することができる。 HOW パラメータに unlink を指定した場合は、標準の unlink 呼び出しをするだけだが、 wipe を指定すると、unlink する前にファイル名を構成するバイトの難読化を行う。 wipesync を指定した場合は、ファイル名を難読化するだけでなく、それを 1 バイトづつディスクに sync することまで行う。留意していただきたいのは、wipesync はデフォルトの方法だが、すべてのファイル名のすべての文字ごとに sync を行うことになるので、負荷が重くなるかもしれないということである。ファイル数が多い場合には、無視できない負荷になるかもしれない。また、使用しているシステムがメタデータの同期アップデートを提供している場合には、やらないでもよいことかもしれない。

-v
--verbose
     shred 処理が進行する間、更新される進行状態の情報のすべてを標準エラーに表示する。

-x
--exact
     デフォルトでは、shred は、通常ファイルのサイズを、ファイルシステムのブロックサイズの倍数に切り上げて、ファイルの最後のブロックの不使用領域まで完全に抹消する。この領域には、システムによっては、たとえば、現在のシステムメモリの一部が入っているかもしれない。この動作を抑制するには、--exact オプションを使用すればよい。すなわち、デフォルトでは、1 ブロック 512 バイトのシステムで 10 バイトの通常ファイルを shred すると、結果として 512 バイトのファイルが出来上がる。だが、このオプションを使えば、shred はファイルの見かけのサイズを増加させないのだ。

-z
--zero
     通常、shred は、最後の 1 回でもランダムデータを書き込む。そんなファイルがハードディスクにあると、(たとえば、暗号化されたデータに見えて) 目立ってしまうのではないかと思うのなら、あるいは、単にそっちの方がもっとすっきりしていると思うのなら、 --zero オプションを指定して、もう一回、 すべて 0 ビットで上書きさせればよい。これは、--iterations オプションで指定した上書き回数のほかに、もう一回ということである。

第 1 ドライブのフロッピーディスクに作成したファイルシステムを跡形もなく消し去るには、次のコマンドを使えばよいだろう。このコマンドで ``1.44MB'' (実際には 1440 KiB) のフロッピーを消去するには、約 20 分かかる。

     shred --verbose /dev/fd0

同様に、ハードディスクの選択したパーティションからすべてのデータを消去するには、以下のコマンドを打ち込めばよい。

     shred --verbose /dev/sda5

最近のディスクでは、1 回の書き込みで十分なはずだ。それならば、書き込みを 3 回行うデフォルトの 3 分の 1 の時間ですむ。

     # 擬似ランダムデータを 1 回書き込む。デフォルトより 3 倍速い。
     shred --verbose -n1 /dev/sda5

念のため、少なくとも 1 回は擬似ランダムデータで上書きをした方がよい。言い換えると、つい使いたくなっても、-n0 --zero を使ってはいけない。ディスク・コントローラの中には、すべてが 0 のブロックを書き込む際に、処理の最適化を行っているものがあり、そのため、ブロック中のバイトすべてがクリアされない恐れがあるからである。 SSD の中には、まさにそういうことをするものがある。

- という FILE は、標準出力を表している。これの使い道は、削除したテンポラリ・ファイルを shred することである。たとえば、次のようにだ。

     i=$(mktemp)
     exec 3<>"$i"
     rm -- "$i"
     echo "Hello, world" >&3
     shred - >&3
     exec 3>&-

しかしながら、shred - >file というコマンドを使っても、ファイルの内容を shred することにはならない。なぜなら、シェルは shred を呼び出す前に、ファイルをサイズ 0 に短縮 (truncate) してしまうからである。 shred file、あるいは (Bourne 互換シェルをお使いなら) shred - 1<>file というコマンドを、代わりに使った方がよい。

終了ステータス 0 は成功を示し、0 以外の値は失敗を示す。

特殊なファイル型
********

この章では、特殊なタイプのファイルを作成するコマンドの説明を行う (さらに rmdir の説明もするが、これはディレクトリという特殊なファイル型の一つを削除するコマンドである)。

Unix 系統のオペレーティング・システムでは、ほかのオペレーティング・システムと比べて、特殊なファイル型というものが著しく少ないが、それでも普通のファイル (normal files) がそうであるような、のっぺらぼうなバイトストリームとして、何でもかんでも扱えさえすればよいというものではない。たとえば、ファイルを作成したり、削除したりするとき、システムはその情報を記録しなければならないが、それはディレクトリ (directory) --- これも特殊なタイプのファイルである --- に書き込まれる。もし興味があれば、ディレクトリを普通のファイルのように読むこともできるが、システムがシステムとしての役割を果たすためには、ディレクトリはそのファイル内容であるバイトに、構造というか、何らかの秩序を持っていなければならない。そういう意味で、ディレクトリは、「特殊な」タイプのファイルなのである。

ディレクトリ以外の特殊なファイル型としては、名前付きパイプ (FIFO)、シンボリックリンク、ソケット、それに、いわゆるスペシャルファイル (special files) がある。

link: システムコール link を使って、ハードリンクを作成する
===================================

link は、一度に 1 個のハードリンクを作成する。これは、システムが提供する link 関数への必要最小のインターフェースである。 See Hard Links (The GNU C Library Reference Manual). 従って、より一般に使われる ln コマンドのような、様々な付加機能をあえて備えていない (see ln invocation)。

書式:

     link FILENAME LINKNAME

FILENAME は、実在するファイルを指していなければならない。また、 LINKNAME は、実在するディレクトリ中の実在しないファイルを指していなければならない。 link は、リンクを作成するために、link (FILENAME, LINKNAME) をコールするだけである。

GNU のシステムでは、このコマンドは、ln --directory --no-target-directory FILENAME LINKNAME と同様に振る舞う。しかし、--directory や --no-target-directory は、POSIX の規格にあるオプションではないので、link の方が、実用上より可搬性がある。

FILENAME がシンボリックリンクの場合、 LINKNAME がシンボリックリンクへのハードリンクになるか、シンボリックリンクの参照先へのハードリンクになるかは、規定されていない。どちらの動作を望むかをはっきり指定したければ、ln -P や ln -L を使用するべきである。

終了ステータス 0 は成功を示し、0 以外の値は失敗を示す。

ln: ファイル間のリンクを作成する
==================

ln はファイル間のリンクを作成する。デフォルトではハードリンクを作成するが、 -s オプションを指定すると、シンボリックリンク (soft linkとも言う) を作ることになる。

書式:

     ln [OPTION]... [-T] TARGET LINKNAME
     ln [OPTION]... TARGET
     ln [OPTION]... TARGET... DIRECTORY
     ln [OPTION]... -t DIRECTORY TARGET...

  * ファイル名を二つ指定すると、ln は 1 番目に対するリンクを 2 番目の名前で作成する。

  * TARGET のみを指定すると、ln はそのファイルに対するリンクをカレントディレクトリに作成する。

  * --target-directory (-t) オプションを指定した場合や、あるいはそれを指定しないでも、最後のファイルがディレクトリであり、しかも --no-target-directory (-T) オプションを指定していない場合は、 ln は各 TARGET ファイルに対するリンクを、指定されたディレクトリに TARGET の名前で作成する。

通常 ln は存在するファイルを削除しない。既存のファイルを無条件で削除するには、--force (-f) オプションを使う。また、ユーザに問い合わせた上で削除するには、--interactive (-i) オプションを使う。既存のファイルを、名前を変更して残すには、--backup (-b) オプションを使用する。(訳注: ここで述べているのは、存在するファイルの名前をリンクファイル名として使う場合の話である。)

ハードリンク (hard link) というのは、存在するファイルが持つ別の名前である。だから、リンクとオリジナルは、区別ができない。専門的な言い方をすると、両者は同じ inode を共有するものである。inode には、ファイルに関する情報がすべて含まれているので、全くのところ、inode こそファイルであると言っても、過言ではないほどだ。たいていのシステムでは、ディレクトリに対するハードリンクの作成は禁じられている。許可されているシステムでも、それができるのは、スーパーユーザだけである (その場合でも、ファイルシステムにループが生じると、ほかの様々なユーティリティ・プログラムで問題が起きるので、慎重に行わなければならない)。なお、ハードリンクは、ファイルシステムの境界を越えることができない。 (もっとも、ハードリンクに対するこうした制限は、POSIX で規定されているわけではない。)

それに対して、シンボリックリンク (symbolic link、略称はシムリンク symlink) は、特殊なファイル型の一つである (すべてのカーネルがサポートしているわけではない。たとえば、System V release 3 やそれ以前のシステムにはシムリンクが存在しない)。このファイル型では、リンクファイルは、実際には別のファイルを、名前を使って参照している。ほとんどのファイル操作では (ファイルのオープン、読み込み、書き出しなど)、シンボリックリンク・ファイルが渡されると、カーネルが自動的にリンクの参照を読み解いて (dereference)、リンクの参照先を操作の対象にする。ただし、操作によっては (たとえば、ファイルの削除)、参照先ではなく、リンクファイルそのものを対象にするものもある。シムリンクの所有者やグループは、リンクを通して行われるファイルアクセスに対して意味を持たないが、削除制限ビットが立っているディレクトリからシンボリックリンクを削除する際には、かかわりを持ってくる。 GNU のシステムでは、シムリンクのモードには意味がなく、変更することもできない。だが、BSD システムの中には、モードが変更でき、ファイル名の解決においてシムリンクをたどるかどうかに影響するものもある。 See Symbolic Links (The GNU C Library Reference Manual).

シンボリックリンクの中身には、どんな文字列が含まれていてもよい。シンボリックリンクに含まれる文字列が、実在するファイルの名前になっていないときは、リンク切れ (dangling symlink) が生ずる。リンク切れのシンボリックリンクを作成することは、禁止されているわけではない。シムリンクの作成に絶対パスを使うか、相対パスを使うかには、それぞれ一長一短がある。絶対パスのシムリンクは、リンクファイルの存在するディレクトリが移動しても、常に同じファイルを指す。もっとも、そのシムリンクが複数のマシンから見えるような場合には (たとえば、ネットワークでつながったファイルシステムにあるような場合には)、リンクが指しているファイルは、必ずしも同じではないかもしれない。相対パスのシンボリックリンクの方は、それが存在しているディレクトリからの相対パスで参照先が決まる。そこで、リンクファイルがネットワークでつながっているマシンからアクセスされることがある場合に、リンクと同じデバイス上に存在するファイルを、そのデバイスのマウントポイントが何という名前かを気にせずに指示することができて、便利であることが多い。

相対パスのシムリンクをカレントディレクトリ以外の場所に作成すると、そのシムリンクが実際に指しているファイルは、同じ文字列がカレントディレクトリを基点として指しているファイルとは別のものになる。そのため、ユーザの多くが、まずカレントディレクトリを変更して、相対パスのシムリンクを作成する場所へ移動することを好んでいる。そうすれば、タブ補完などのファイル名参照方法を用いて、シムリンクに格納する参照先の適切な相対パスを見つけることができるからである。

このプログラムでは以下のオプションが使用できる。参照: Common options.

-b
--backup[=METHOD]
     See Backup options.  そのままでは、上書きされるか、消去されてしまう各ファイルのバックアップを作成する。

-d
-F
--directory
     ユーザが適切な権限を持っていれば、ディレクトリに対するハードリンクを作成しようとしても許可する。とは言え、たぶんシステムによって禁止されているので、たとえスパーユーザでも作成に失敗するだろう。

-f
--force
     リンクの作成先に、作成するリンクファイルと同名のファイルがすでに存在していたら、それを削除する。

-i
--interactive
     リンクの作成先に、作成するリンクファイルと同名のファイルがすでに存在していたら、削除するかどうか、ユーザに問い合わせる。

-L
--logical
     -s オプションが有効になっていないとき、リンク対象として指定されたファイル (訳注: 上記書式の TARGET) がシンボリックリンクならば、シンボリックリンクそのものではなく、シンボリックリンクが参照しているファイルへのハードリンクを作成する。

-n
--no-dereference
     最後のオペランドがディレクトリに対するシンボリックリンクであるとき、それをディレクトリとして特別扱いしない (訳注: すなわち、ディレクトリ内に TARGET と同名でリンクを作ることはしない)。むしろ、普通のファイルであるかのように扱う。

     リンクの作成先として指定されたのが (ディレクトリに対するシムリンクではなく) 本物のディレクトリならば、曖昧なところは全くない。そのディレクトリ内にリンクを作るだけの話だ。ところが、指定された作成先が、ディレクトリに対するシムリンクの場合は、ユーザの要求を処理するのに、二つの行き方がある。 ln は、通常のディレクトリを扱う場合と全く同じように作成先を扱って、そこにリンクを作成することができる。あるいは、作成先をディレクトリではないもの、すなわち、他ならぬシムリンクと見なすことも可能だ。後者の場合、ln は、新しいリンクを作成する前に、そのシムリンクを消去するなり、バックアップするなりしなければならない。 ln のデフォルトは、作成先がディレクトリに対するシムリンクであっても、ディレクトリと全く同様に扱うことである。

     このオプションは、--no-target-directory (-T) の弱いバージョンである。従って、両方のオプションを指定した場合、こちらは効果がない。

-P
--physical
     -s オプションが有効になっていないとき、リンク対象として指定されたファイル (訳注: 上記書式の TARGET) がシンボリックリンクならば、シンボリックリンクそのものへのハードリンクを作成する。そういった動作をカーネルがサポートしていないプラットホームでは、このオプションを指定すると、リンク対象のシンボリックリンクと全く同じ内容を持つシンボリックリンクが作成される。このとき、シンボリックリンクの内容に手が加えられることは決してないので、どちらのシンボリックリンクを使って行われるファイル名の解決も、シンボリックリンクへのハードリンクが作成された場合と結局同じになる。

-r
--relative
     リンクファイルを置く場所を基点とする相対パスのシンボリックリンクを作成する。

     用例:

          ln -srv /a/file /tmp
          '/tmp/file' -> '../a/file'

     相対パスのシンボリックリンクは、それを置くディレクトリと参照先のファイル名を正規化した上で、それに基づいて作成される。すなわち、そうしたファイル名中にあるすべてのシンボリックリンクは、実体に還元されることになるわけだ。なお、realpath コマンドを使用すれば、以下の例に示すように、相対パスを生成する際にもっと融通が利く (訳注: たとえば、realpath を使うと、ファイル名中のシンボリックリンクをシンボリックリンクのままにしておくこともできる)。 See realpath invocation.

          ln--relative() {
            test "$1" = --no-symlinks && { nosym=$1; shift; }
            target="$1";
            test -d "$2" && link="$2/." || link="$2"
            rtarget="$(realpath $nosym -m "$target" \
                        --relative-to "$(dirname "$link")")"
            ln -s -v "$rtarget" "$link"
          }

-s
--symbolic
     ハードリンクではなく、シンボリックリンクを作る。このオプションは、シンボリックリンクをサポートしていないシステムでは、エラー・メッセージを表示するだけである。

-S SUFFIX
--suffix=SUFFIX
     -b によって作られる各バックアップファイルの後ろに SUFFIX を付ける。 See Backup options.

-t DIRECTORY
--target-directory=DIRECTORY
     DIRECTORY を出力先ディレクトリに指定する。 See Target directory.

-T
--no-target-directory
     最後のオペランドがディレクトリやディレクトリへのシンボリックリンクでも、それを特別扱いしない。 See Target directory.

-v
--verbose
     リンクの作成に成功した後で、各ファイルの名前を表示する。

-L と -P の両方を指定すると、最後に指定したものが効果を持つ。さらに -s も指定した場合は、エラーや警告は出ないが、-L や -P は無視される。-L と -P のどちらのオプションも指定しない場合、ln のこの実装では、システムの link 関数がシンボリックリンクに対するハードリンクをサポートしていれば (たとえば、GNU のシステム)、デフォルトの動作は -P になる。 link 関数がシンボリックリンクをたどるものならば (たとえば、BSD)、デフォルトの動作は -L である。

終了ステータス 0 は成功を示し、0 以外の値は失敗を示す。

用例:

     悪い例:

     # カレントディレクトリにあるファイル a を指す ../a というリンクを
     # 作成する。実のところ役に立たない。../a が自分自身を指すリンクに
     # なってしまうからだ。
     ln -s a ..

     よりよい例:

     # 頭がこんがらかってしまわないように、シムリンクを作成する前に、
     # リンクを作るディレクトリに移動する。
     cd ..
     ln -s adir/a .

     悪い例:

     # 絶対パスによるリンク対象の指定は、リンク対象の位置が変わると、
     # 役に立たない。
     ln -s $(pwd)/a /some/dir/

     よりよい例:

     # 相対パスによるリンク対象の指定は、リンクやその対象を含む
     # ディレクトリが移動しても、両者の相対的な位置関係が変わらない
     # かぎり、問題がない。また、ネットワークでつながったファイル
     # システム間でも通用する。
     ln -s afile anotherfile
     ln -s ../adir/afile yetanotherfile

mkdir: ディレクトリを作成する
==================

mkdir は、指定された名前でディレクトリを作成する。

書式:

     mkdir [OPTION]... NAME...

mkdir は、NAME で指定された各ディレクトリを、指定された順番で作成する。 NAME がすでに存在していると、エラーになり、その旨メッセージを出すが、 NAME がすでに存在していても、-p オプションが指定され、NAME がディレクトリの場合は、エラーにならない。

このプログラムでは以下のオプションが使用できる。参照: Common options.

-m MODE
--mode=MODE
     作成するディレクトリの許可属性ビットを MODE に設定する。MODE には chmod と同じ書式を使用し、a=rwx (すべてのユーザに、読み、書き、実行を許可する) を基点とする。See File permissions.

     通常、ディレクトリには、作成された時点で、要求したとおりのファイル・モードビットが付く。 GNU の拡張として、MODE で特殊モードビットも指定できるが、その場合は、ディレクトリは存在しているが、特殊モードビットは要求どおりではないという、時間の隙間が生じるかもしれない。ディレクトリの set-user-ID ビットと set-group-ID ビットが、このオプションを使って変更しない場合にどのように継承されるかについては、次の節を参照していただきたい。See Directory Setuid and Setgid.

-p
--parents
     各引数について、存在していない親ディレクトリがあれば、それを作成し、その許可属性ビットを umask を基にして u+wx になるように設定する。親ディレクトリがすでに存在している場合は、このオプションは何もせず、その許可属性ビットを変更することもない。

     新たに作成するいかなる親ディレクトリの許可属性ビットも、u+wx を含むある一定の値に設定するには、mkdir を実行する前に、umask を設定すればよい。たとえば、(umask u=rwx,go=rx; mkdir -p P/Q) というシェルコマンドで P という親ディレクトリを作れば、その許可属性ビットは u=rwx,go=rx になる。また、親ディレクトリに特殊モードビットも設定するには、 chmod を mkdir の後で実行すればよい。新たに作成される親ディレクトリの set-user-ID ビットと set-group-ID ビットがどのように継承されるかについては、次の節を参照していただきたい。 See Directory Setuid and Setgid.

-v
--verbose
     ディレクトリを作成するごとに、メッセージを表示する。--parents と併せて使うと、大変便利である。

     (CONTEXT を省略できるのは、coreutils-8.22 から)

終了ステータス 0 は成功を示し、0 以外の値は失敗を示す。

mkfifo: FIFO (名前付きパイプ) を作成する
============================

mkfifo は、指定された名前で FIFO (名前付きパイプ named pipes とも言う) を作成する。

書式:

     mkfifo [OPTION] NAME...

FIFO は特殊なファイル型の一つであり、これを利用すると、独立したプロセスの間でデータのやりとりが可能になる。片方のプロセスが FIFO を書き出し用にオープンし、もう一方のプロセスが読み込み用にオープンする。そうすると、シェルなどにある普通の名前のない (anonymous) パイプを使ったときのように、データを一方から他方へ流すことができるのである。

このプログラムでは以下のオプションが使用できる。参照: Common options.

-m MODE
--mode=MODE
     作成する FIFO の許可属性を MODE にする。MODE は chmod で使用するのと同じシンボル表記であり、a=rw (すべてのユーザに、読み、書きを許可する) を基点として使う。MODE で指定するのは、ファイルの許可属性ビットのみにするべきである。 See File permissions.

     (CONTEXT を省略できるのは、coreutils-8.22 から)

終了ステータス 0 は成功を示し、0 以外の値は失敗を示す。

mknod: ブロック型やキャラクタ型のスペシャルファイルを作成する。
===================================

mknod は、指定された名前で FIFO、キャラクター・スペシャルファイル、ブロック・スペシャルファイルを作成する。

書式:

     mknod [OPTION]... NAME TYPE [MAJOR MINOR]

これまでに使ってきた「特殊なファイル型 (``special file type'')」という言い回しとは違って、「スペシャルファイル (special file)」という用語には、Unix では技術的な意味が存在する。すなわち、それは、データを生成したり、受け取ったりできるもののことである。たいていの場合、それはハードウェアという物理的なものを指し、たとえば、プリンタやディスクがそれに当たる。(なお、そうしたスペシャルファイルは、通常、システムの設定時に作られる。) mknod は、このタイプのファイルを作成するコマンドである。そうしたデバイスには、そこから一度に 1 文字 (a character) づつしか読むことのできないものもあれば、一度に 1 ブロックを (すなわち、たくさんの character を) 読み込むことのできるものもある。それ故、スペシャルファイルには、ブロック・スペシャルファイル (block special files) とキャラクタ・スペシャルファイル (character special files) があると言われるのである。

シェルの組み込み機能の mknod やエイリアスのために、 mknod に何の修飾も付けずに対話的に使ったり、スクリプトの中で使ったりすると、動作がここで述べているものとは違うことがあるかもしれない。シェルによる干渉を避けるためには、env 経由で mknod を起動すればよい (すなわち、env mknod ... のようにだ)。

NAME に続く引数では、作成するファイルのタイプを指定する。

p
     FIFO を作成する

b
     ブロック・スペシャルファイルを作成する

c
     キャラクタ・スペシャルファイルを作成する

ブロック型やキャラクタ型のスペシャルファイルを作成する際には、ファイルタイプに続いて、メージャー・デバイス番号とマイナー・デバイス番号を指定する必要がある。メージャーやマイナーのデバイス番号が 0x や 0X で始まっていれば、番号は 16 進数と見なされる。0 で始まっていれば 8 進数、それ以外の場合は 10 進数である。

このプログラムでは以下のオプションが使用できる。参照: Common options.

-m MODE
--mode=MODE
     作成するファイルの許可属性を MODE にする。MODE は chmod で使用するのと同じシンボル表記であり、a=rw を基点として使う。 MODE で指定するのは、ファイルの許可属性ビットのみにするべきである。 See File permissions.

     (CONTEXT を省略できるのは、coreutils-8.22 から)

終了ステータス 0 は成功を示し、0 以外の値は失敗を示す。

readlink: シムリンクの値、または正規化されたファイル名を表示する
=====================================

readlink には、二つの動作モードがある。

Readlink モード

     このモードでは、readlink は、指定されたシンボリックリンクの値を表示する。引数がシンボリックの名前以外だったときは、何も出力せず、0 以外の終了コードで終了する。

Canonicalize (正規化) モード

     このモードでは、readlink は、指定されたファイルの絶対パスによる名前を表示する。その絶対パスには、. や .. といった構成要素や重複するパスの区切り (/)、シンボリックリンクは含まれない。

     readlink [OPTION]... FILE...

デフォルトでは、readlink は readlink モードで動作する。

このプログラムでは以下のオプションが使用できる。参照: Common options.

-f
--canonicalize
     canonicalize モードで動かす。ファイル名を構成する要素のうち、最後の要素以外のどれかが、存在しなかったり、利用できなかったりすると、 readlink は何も出力せず、0 以外の終了コードで終了する。引数の末尾のスラッシュは無視される。

-e
--canonicalize-existing
     canonicalize モードで動かす。ファイル名を構成する要素に、存在しなかったり、利用できなかったりするものがあれば、readlink は何も出力せず、 0 以外の終了コードで終了する。ファイル名のの末尾にスラッシュを付けると、その名前はディレクトリであるという指定になる。

-m
--canonicalize-missing
     canonicalize モードで動かす。ファイル名を構成する要素に、存在しなかったり、利用できなかったりするものがあれば、readlink はそれをディレクトリと見なす。

-n
--no-newline
     FILE が 1 個しか指定されなかったときは、出力の区切り文字 (訳注: 通常は改行) を表示しない。複数の FILE とともに、このオプションが指定されたときは、警告メッセージを出す。

-s
-q
--silent
--quiet
     ほとんどのエラーメッセージを出さないようにする。デフォルトで ON になっている。

-v
--verbose
     エラーメッセージを表示する。

-z
--zero
     各行の末尾に改行ではなく、ゼロバイト (ASCII NUL) を出力する。このオプションを使用すると、出力するデータの途中に改行が現れる場合でも、他のプログラムがその出力を解析できるようになる。

readlink ユーティリティが初めて登場したのは、OpenBSD 2.1 だった。

realpath コマンドをオプションなしで使うと、canonicalize モードの readlink と同じ動作をする。

終了ステータス 0 は成功を示し、0 以外の値は失敗を示す。

rmdir: 空のディレクトリを削除する
====================

rmdir は、空のディレクトリを削除する。

書式:

     rmdir [OPTION]... DIRECTORY...

引数 DIRECTORY が実在する空のディレクトリを指していない場合、エラーになる。

このプログラムでは以下のオプションが使用できる。参照: Common options.

--ignore-fail-on-non-empty
     ディレクトリの削除に失敗しても、その理由が単にディレクトリが空ではないせいならば、その失敗を無視する。

-p
--parents
     DIRECTORY を削除するとき、DIRECTORY を構成する各要素の削除を試みる。そこで、たとえば、rmdir -p a/b/c は、rmdir a/b/c a/b a と同じになる。従って、そうしたディレクトリのどれかが空ではないことが判明すると、動作に失敗する。動作に失敗しても、エラーメッセージを出して失敗のステータスで終了しないようにするには、 --ignore-fail-on-non-empty オプションを使えばよい。

-v
--verbose
     DIRECTORY の削除に成功するごとに、その旨メッセージを出す。

空ではないディレクトリを (再帰的に) 削除する方法については、rm コマンドの説明を参照していただきたい。See rm invocation.

終了ステータス 0 は成功を示し、0 以外の値は失敗を示す。

unlink: システムコール unlink を使って、ファイルを削除する
=====================================

unlink は、指定された 1 個のファイル名の削除を行う。これは、システムが提供する unlink 関数への必要最小のインターフェースである。 See Deleting Files (The GNU C Library Reference Manual). 従って、より一般に使われる rm コマンドのような、様々な付加機能をあえて備えていない (see rm invocation)。

書式:

     unlink FILENAME

システムによっては、unlink を使って、ディレクトリの名前を削除できるものもある。また、それができるのは、特権を持ったユーザだけであるシステムもある。 GNU のシステムでは、unlink は、ディレクトリの名前を全く削除できない。

unlink コマンドは、--help と --version オプションを認識する。名前が - で始まるファイルを削除するには、名前の前に ./ を付ければよい。たとえば、unlink ./--help のようにだ。

終了ステータス 0 は成功を示し、0 以外の値は失敗を示す。

ファイルの属性変更
*********

ファイルについては、内容と名前とファイル型 (see Special file types) で、すべてが尽くされるわけではない。ファイルには、他の情報も存在する。たとえば、所有者 (ユーザ ID)、グループ (グループ ID)、アクセス権 (そのファイルに対して、所有者、グループに属するユーザ、それ以外の一般ユーザは、それぞれ何ができるのか)、様々なタイムスタンプ、といった情報も存在するのである。そうしたものは、一まとめにして、ファイルの属性 (attributes) と呼ばれている。

以下のコマンドは、ファイルの属性を変更する。

chown: ファイルの所有者やグループを変更する
=========================

chown は、指定された各 FILE の所有者や所有グループを NEW-OWNER に変更する。所有者とグループを、存在する参照用ファイル (reference file) のそれと同じものに変更することもできる。

書式:

     chown [OPTION]... {NEW-OWNER | --reference=REF_FILE}
      FILE...

NEW-OWNER では、新しい所有者やグループを以下のような形で指定する (: の前後に空白を入れてはいけない)。

     [OWNER] [ : [GROUP] ]

細かく説明しよう。

owner
     OWNER (ユーザ名、またはユーザ ID 番号) だけが指定されている場合は、そのユーザが指定された各ファイルの所有者になる。ファイルのグループは変化しない。

owner:group
     OWNER の後に、コロンと GROUP (グループ名、またはグループ ID 番号) が、間に空白をはさまずに続く場合は、ファイルの所有グループも (GROUP に) 変更される。

owner:
     OWNER の後ろにコロンがあるのみで、グループ名が続かない場合は、そのユーザがファイルの所有者になり、ファイルのグループは、OWNER のログイン・グループに変更される。

:group
     コロンとそれに続く GROUP のみが指定され、所有者が省略されている場合は、ファイルのグループだけが変更される。この場合、chown は、chgrp と同じ動作をするわけだ。

:
     コロンのみが指定されている場合や、NEW-OWNER に何も指定されていない場合は、所有者もグループも変更されない。

OWNER や GROUP にユーザ ID 番号やグループ ID 番号を使用する場合は、番号の頭に + を付ければ、ID 番号だと明示することができる。 See Disambiguating names and IDs.

古めのスクリプトの中には、区切りの印として : ではなく、. を今だに使っているものがあるかもしれない。POSIX 1003.1-2001 (see Standards conformance) では、これに対するサポートを要求していないが、後方互換のために、GNU の chown では、曖昧さが生じないかぎり、. の使用をサポートしている。とは言え、新しく書くスクリプトでは、. の使用を避けるべきである。他のシステムでも使えるとはかぎらないし、また、OWNER.GROUP という全体が、名前に . を含むユーザを指していたりすると、不都合が生じるからだ。

ユーザがグループを任意のものに変更できるか、それとも、
グループの設定はユーザがその一員であるグループにのみ制限されるという、
より可搬性のある動作になっているかは、システム次第である。

chown コマンドを実行すると、set-user-ID ビットや set-group-ID ビットが消えてしまうことがある。そうしたことが起きるかどうかは、裏で動いている chown システムコールのポリシーや機能次第であり、従って、システムによるファイルモードの変更が、chown コマンドのコントロール外になることがあるのだ。しかるべき特権を持ったユーザが実行した場合や、問題のビットが実行権とは関係のない何か別の機能 (たとえば、強制ロック) を表している場合などでは、chown コマンドを実行しても、そうしたビットが変わらないかもしれない。どうなるかよくわからない場合は、裏で動いているシステムの動作を調べるとよい。

このプログラムでは以下のオプションが使用できる。参照: Common options.

-c
--changes
     所有者の変更が実際に行われた各 FILE について、何を実行したかを詳しく表示する。

-f
--silent
--quiet
     所有者を変更できないファイルがあっても、エラーメッセージを出さない。

--from=OLD-OWNER
     FILE が OLD-OWNER で指定された属性を現在持っているときにのみ、その所有者を変更する。OLD-OWNER の書式は、上記の NEW-OWNER と同じである。このオプションは、ファイルの不正使用が可能になる時間を大幅に狭めるという点で、主としてセキュリティの見地から役に立つ。一例を挙げると、この種のオプションを使わない場合、ユーザの ID 番号の変更を、そのユーザのファイルに反映させるために、root は次のようなコマンドを実行するかもしれない。

          find / -user OLDUSER -print0 | xargs -0 chown -h NEWUSER

     しかし、これは危険なことである。なぜなら、find が存在するファイルの所有者を検査するときと、chown が実際に実行されるときとの間に時間差があり、それはかなり大きいかもしれないからだ。この時間差を小さくする方法の一つは、ファイルが見つかるごとに、chown を実行することだろう。

          find / -user OLDUSER -exec chown -h NEWUSER {} \;

     しかし、動作の対象になるファイルがたくさんあると、この方法は非常に時間がかかる。 --from=OLD-OWNER オプションを使う方が、万全とまでは言えないにしても、より安全である (時間差がさらに小さくなるので)。

          chown -h -R --from=OLDUSER NEWUSER /

--dereference
     シンボリックリンクそのものを動作の対象とせず、リンクが指しているものを動作の対象にする。これがデフォルトである。

-h
--no-dereference
     シンボリックリンクが指しているものではなく、シンボリックリンクそのものを動作の対象にする。このモードは、システムコール lchown に依存している。システムコール lchown を提供していないシステムでは、コマンドラインで指定されたファイルがシンボリックリンクだと、chown は実行に失敗する。なお、再帰的にディレクトリ階層をたどっている際にシンボリックリンクに出会っても、デフォルトでは診断メッセージを表示しない。ただし、--verbose を指定している場合は別なので、そちらの説明も参照していただきたい。

--preserve-root
     ルートディレクトリ (/) を再帰的に変更しようとした時点で、実行に失敗する。 --recursive オプションを指定していない場合、このオプションは効果がない。 See Treating / specially.

--no-preserve-root
     --preserve-root オプションが前にあれば、その効果を無効にする。 See Treating / specially.

--reference=REF_FILE
     各 FILE の所有者とグループを REF_FILE のそれと同じものに変更する。 REF_FILE がシンボリックリンクの場合は、シンボリックリンクの所有者とグループではなく、リンクが指しているファイルの所有者とグループを使用する。

-v
--verbose
     処理したすべてのファイルについてメッセージを表示する。システムコール lchown を持っていないシステムで、再帰的にディレクトリ階層をたどっている際にシンボリックリンクに出会った場合、 --no-dereference が有効になっていれば、「シンボリックリンクもその参照先も変更しない」というメッセージを出す。

-R
--recursive
     ディレクトリとその中身の所有者を再帰的に変更する。

     See Traversing symlinks.

     See Traversing symlinks.

     See Traversing symlinks.

終了ステータス 0 は成功を示し、0 以外の値は失敗を示す。

用例:

     # /u の所有者を "root" に変更する。
     chown root /u

     # 同様だが、グループも "staff" に変更する。
     chown root:staff /u

     # /u 及び、それ以下にあるファイルの所有者を "root" に変更する。
     chown -hR root /u

chgrp: ファイルの所有グループを変更する
=======================

chgrp は、指定された各 FILE の所有グループを GROUP に変更する (GROUP は、グループ名でもグループ ID 番号でもよい)。所有グループを、存在する参照用ファイル (reference file) のグループと同じものに変更することもできる。 See chown invocation.

書式:

     chgrp [OPTION]... {GROUP | --reference=REF_FILE}
      FILE...

GROUP にグループ ID 番号を使用する場合は、番号の頭に + を付ければ、 ID 番号だと明示することができる。 See Disambiguating names and IDs.

ユーザがグループを任意のものに変更できるか、それとも、
グループの設定はユーザがその一員であるグループにのみ制限されるという、
より可搬性のある動作になっているかは、システム次第である。

このプログラムでは以下のオプションが使用できる。参照: Common options.

-c
--changes
     グループの変更が実際に行われた各 FILE について、何を実行したかを詳しく表示する。

-f
--silent
--quiet
     グループを変更できないファイルがあっても、エラーメッセージを出さない。

--dereference
     シンボリックリンクそのものを動作の対象とせず、リンクが指しているものを動作の対象にする。これがデフォルトである。

-h
--no-dereference
     シンボリックリンクが指しているものではなく、シンボリックリンクそのものを動作の対象にする。このモードは、システムコール lchown に依存している。システムコール lchown を提供していないシステムでは、コマンドラインで指定されたファイルがシンボリックリンクだと、chgrp は実行に失敗する。なお、再帰的にディレクトリ階層をたどっている際にシンボリックリンクに出会っても、デフォルトでは診断メッセージを表示しない。ただし、--verbose を指定している場合は別なので、そちらの説明も参照していただきたい。

--preserve-root
     ルートディレクトリ (/) を再帰的に変更しようとした時点で、実行に失敗する。 --recursive オプションを指定していない場合、このオプションは効果がない。 See Treating / specially.

--no-preserve-root
     --preserve-root オプションが前にあれば、その効果を無効にする。 See Treating / specially.

--reference=REF_FILE
     各 FILE のグループを REF_FILE のグループと同じものに変更する。 REF_FILE がシンボリックリンクの場合は、シンボリックリンクのグループではなく、リンクが指しているファイルのグループを使用する。

-v
--verbose
     処理したすべてのファイルについてメッセージを表示する。システムコール lchown を持っていないシステムで、再帰的にディレクトリ階層をたどっている際にシンボリックリンクに出会った場合、 --no-dereference が有効になっていれば、「シンボリックリンクもその参照先も変更しない」というメッセージを出す。

-R
--recursive
     ディレクトリとその中身の所有グループを再帰的に変更する。

     See Traversing symlinks.

     See Traversing symlinks.

     See Traversing symlinks.

終了ステータス 0 は成功を示し、0 以外の値は失敗を示す。

用例:

     # /u のグループを "staff" に変更する。
     chgrp staff /u

     # /u 及び、それ以下にあるファイルのグループを "staff" に変更する。
     chgrp -hR staff /u

chmod: アクセス権を変更する
=================

chmod は、名前を指定したファイルのアクセス権を変更する。

書式:

     chmod [OPTION]... {MODE | --reference=REF_FILE}
      FILE...

chmod コマンドがシンボリックリンクのアクセス権を変更することはない。 chmod システムコールがシンボリックリンクのアクセス権を変更できないからである。シンボリックリンクのアクセス権が利用されることは全くないので、この制限は問題にならない。とは言え、コマンドラインで指定された FILE が、シンボリックリンクだということはあるだろうが、そうした場合、chmod は、指定された各シンボリックリンクが参照しているファイルのアクセス権を変更する。それに対して、ディレクトリを再帰的にたどっている最中にシンボリックリンクに出会った場合は、 chmod はそれを無視することになる。

chmod の実行に成功したとき、通常ファイルの set-group-ID ビットが消えることがあるが、それは、ファイルのグループ ID が、chmod を実行したユーザの実効グループ ID や、補助グループ ID の一つに一致しなかった場合である。もっとも、そのユーザがしかるべき特権を持っている場合には、 set-group-ID ビットが消えることはない。また、制限事項が他にも存在して、指定した MODE 中や REF_FILE の、set-user-ID ビットや set-group-ID ビットが無視されることもある。そうした動作は、裏で動いている chmod システムコールのポリシーや機能次第なのだ。どうなるかよくわからない場合には、裏で動いているシステムの動作を調べればよい。

MODE には、ファイルの新しいモードビット (訳注: すなわち、アクセス権) を指定する。詳細については、「ファイルの許可属性」の章を参照していただきたい (see File permissions)。MODE を指定するとき、MODE をどうしても - で始めたいのなら、前に -- を置いた方がよい。たとえば、chmod -- -w file のようにだ。とは言え、たいていの場合、chmod a-w file の方が望ましい。なお、chmod -w file (-- がない) が chmod a-w file と別の動作になる場合には、警告が出る。

このプログラムでは以下のオプションが使用できる。参照: Common options.

-c
--changes
     アクセス権の変更が実際に行われた各 FILE について、何を実行したかを詳しく表示する。

-f
--silent
--quiet
     アクセス権が変更できないファイルがあっても、エラーメッセージを出さない。

--preserve-root
     ルートディレクトリ (/) を再帰的に変更しようとした時点で、実行に失敗する。 --recursive オプションを指定していない場合、このオプションは効果がない。 See Treating / specially.

--no-preserve-root
     --preserve-root オプションが前にあれば、その効果を無効にする。 See Treating / specially.

-v
--verbose
     すべての FILE について、何を実行し、何を実行しなかったかを詳しく表示する。

--reference=REF_FILE
     各 FILE のモードを REF_FILE のそれと同じものに変更する。 See File permissions.  REF_FILE がシンボリックリンクの場合は、シンボリックリンクのモードではなく、リンクが参照しているファイルのモードを使用する。

-R
--recursive
     ディレクトリとその中身のアクセス権を再帰的に変更する。

終了ステータス 0 は成功を示し、0 以外の値は失敗を示す。

touch: ファイルのタイムスタンプを変更する
========================

touch は指定されたファイルのアクセス日時 (access time) や更新日時 (modification time) を変更する。

書式:

     touch [OPTION]... FILE...

引数 FILE に存在しないファイルを指定すると、空のファイルが作成される。ただし、--no-create (-c) や --no-dereference (-h) が有効な場合は、ファイルは作成されない。

引数 FILE が - という文字列の場合は、特別な扱いをする。touch は、標準出力に結びついているファイルの日時を変更するのである。

touch は、デフォルトではファイルのタイムスタンプを現在の日時にセットする。 touch はオペランドを左から右へと順番に処理するので、生成されたタイムスタンプが、前後のオペランドで一致しないこともある。また、「現在」とはいつかを決めるのは、プラットフォーム次第である。ネットワーク・ファイルシステムを使用しているプラットフォームでは、オペレーティング・システムとファイルシステムとで別のクロックを使用していることも珍しくない。 touch は通常、デフォルトではファイルシステムのクロックを使用するので、クロックのずれのために、生成されたファイルのタイムスタンプが、あるプログラムにとっては「未来」に見えたり、「過去」に見えたりすることがある。

touch コマンドは、ファイルのタイムスタンプを、ユーザが指定した日時よりも精度が高くならない範囲で、表現できる最も精密な値にセットする。この値がユーザが指定した日時と違うことがあるが、それにはいくつかの理由がある。第一に、ユーザが指定した日時が、サポートされている精度を越えていることがある。第二に、ファイルシステムが、日時のタイプによって別の精度を使っていることがある。第三に、ファイルのタイムスタンプが、オペレーティング・システムのタイムスタンプとは別の精度を使っていることがある。第四に、オペレーティング・システムでタイムスタンプの更新に使用される基本データ型が、さらに違う精度を採用していることがある。そんなわけで、理屈の上では、たとえば、ファイルシステムでは、アクセス日時には 10 マイクロ秒の精度を、更新日時には 100 ナノ秒の精度を使用し、オペレーティング・システムの方では、現在の時刻にはナノ秒の精度を、 touch がファイルのタイムスタンプを任意の値に設定するために使う基本データ型には、マイクロ秒の精度を使用している、そういうこともありえるのである。

タイムスタンプを現在の時刻にセットする場合には、ユーザが所有していないファイルでも、書き込み権限さえ持っていれば、touch はそのタイムスタンプを変更することができる。しかし、現在の時刻以外にセットするには、ユーザはそのファイルを所有していなければならない。古いシステムの中には、制限がさらに厳しいものもある。たとえば、アクセス日時と更新日時の両方を現在の時刻にセットするとき以外、対象となるファイルを所有していなければならないといった具合だ。

touch が提供するオプションを使えば、ファイルの 2 種類の日時 --- 最終アクセス日時と最終更新日時 --- を変更することができるが、標準の日時には、実はそのほかに 3 番目のものがある。すなわち、inode の変更日時 (inode change time) だ。これは、ファイルの ctime と呼ばれることが多い。 inode の変更日時は、ファイルのメタ情報が最後に変更された日時を表している。メタ情報の変更のよくある例の一つは、ファイルのアクセス権の変更である。アクセス権の変更では、ファイルにアクセスするわけではないので、atime (アクセス日時) は変化しないし、またファイルの内容を変更するわけでもないので、mtime (更新日時) も変化しない。しかし、ファイルそのものに関する何ものかが変化しているわけであり、それはどこかに記録されなければならない。まさにそれが、inode の ctime フィールドの役割なのだ。たとえば、バックアップ・プログラムが、ファイルのアクセス権に変更があった場合も含めて、ファイルのコピーを最新に保つことができるようにするには、ctime が不可欠である。ファイルの ctime は変更するが、他の日時には影響を及ぼさない別の操作には、ファイル名の変更がある。なお、いかなる場合であれ、通常の操作では、ユーザが ctime フィールドを自分で指定する値に変更することはできない。オペレーティングシステムやファイルシステムの中には、4 番目の日時をサポートしているものもある。すなわち、作成日時 (birth time) であり、ファイルが最初に作られた日時だ。名前からして当然だが、このタイムスタンプが変更されることはない。

タイムスタンプは、タイムゾーンのルールに従うが、そのルールを指定しているのは、環境変数 TZ である。 TZ が設定されていない場合は、システムのデフォルトのルールに従う。 See Specifying the Time Zone with TZ (The GNU C Library Reference Manual). なお、UTC のタイムスタンプを使えば、夏 (冬) 時間への移行時の曖昧さを避けることができる。

このプログラムでは以下のオプションが使用できる。参照: Common options.

-a
--time=atime
--time=access
--time=use
     アクセス日時のみ変更する。

-c
--no-create
     存在しないファイルについて警告を出さず、ファイルの作成もしない。

-d TIME
--date=TIME
     現在の日時の代わりに TIME を使用する。TIME には、月の名前、タイムゾーン、am や pm、yesterday なども使うことができる。たとえば、--date="2004-02-27 14:19:13.489392193 +0530" とすると、 UTC より 5 時間 30 分東のタイムゾーンで、2004 年 2 月 27 日 午後 2 時 19 分 13 秒 から 489,392,193 ナノ秒経過した瞬間を指定することになる。 See Date input formats.  精度の高いタイムスタンプをサポートしていないファイルシステムでは、精度の超過分は単に無視される。

-f
     何もしない。BSD 版の touch との互換性のためにある。

-h
--no-dereference
     シンボリックリンクが参照しているファイルではなく、シンボリックリンクのタイムスタンプの変更を試みる。このオプションを使用した場合、空のファイルは作成されないが、ファイルが存在しないという警告まで出ないようにするには、-c オプションも併せて使用する必要がある。すべてのシステムが、シンボリックリンクのタイムスタンプの変更をサポートしているわけではない。なぜならば、POSIX 2008 までは、下層で動いているシステムに対して、そうした動作のサポートを要求していなかったからだ。また、システムによっては、シンボリックリンクは、調べるだけでアクセス日時が変わってしまうので、変更の結果が後々まで残って観察できるのは、更新日時だけだというものもある。なお、このオプションを -r オプションと一緒に使用すると、参照するタイムスタンプが、リンクが指しているファイルからではなく、シンボリックリンクから取得される。

-m
--time=mtime
--time=modify
     更新日時 (modification time) のみ変更する。

-r FILE
--reference=FILE
     現在の日時の代わりに、参照ファイル FILE の日時を使用する。このオプションを --date=TIME (-d TIME) オプションと組み合わせて使うと、TIME が相対時間で指定されている場合は、参照ファイル FILE の日時がその基点となるが、それ以外の場合は、FILE の日時は無視される。たとえば、-r foo -d '-5 seconds' は、foo のタイムスタンプより 5 秒前のタイムスタンプを指定している。 FILE がシンボリックリンクの場合は、-h が同時に有効になっていないかぎり、参照するタイムスタンプは、シンボリックリンクの参照先から取得される。

-t [[CC]YY]MMDDHHMM[.SS]
     現在の日時の代わりに、-t オプションの引数を使用する (引数の構成は、4 桁または 2 桁の年 (省略可)、月、日、時、分、秒 (秒も省略可) である)。年が 2 桁のみ指定された場合、0 ... 68 の範囲の年ならば、 CC は 20 であり、69 ... 99 の範囲の年では、CC は 19 である。年が全く指定されない場合は、引数は今年の日付だと解釈される。閏秒に対応している例外的なシステムでは、SS が 60 のこともありえる。

POSIX 1003.1-2001 以前のシステムでは、touch は次のような旧式の書式をサポートしている。すなわち、-d, -r, -t オプションのいづれによってもタイムスタンプが指定されていず、しかも、2 個以上の FILE が指定されていて、最初の FILE が MMDDHHMM[YY] の形を持ち、それが (YY が存在するなら、それを先頭に移せば) -t オプションに対する有効な引数と見なすことができる場合に、その引数の表している年度が 1969--1999 の範囲にあるならば、その引数をファイル名ではなく、他のファイルに適用する日時と解釈する、というものである。この旧式の動作は、環境変数 _POSIX2_VERSION によってコントロールすることができるが (see Standards conformance)、移植を考慮したスクリプトでは、動作がこの環境変数に依存するコマンドの使用は避けるべきである。たとえば、二通りの解釈ができる touch 12312359 main.c を使うより、touch ./12312359 main.c や touch -t 12312359 main.c を使用した方がよい。

終了ステータス 0 は成功を示し、0 以外の値は失敗を示す。

ディスク使用量
*******

データをいくらでも無限に入れることのできるディスクはない。この章で説明するコマンドには、使用しているディスク容量や利用可能なディスク容量を報告するもの、それ以外のファイル情報やファイルステータス情報を報告するもの、それに、バッファの内容をディスクに書き込むものがある。

df: ファイルシステムのディスク使用状態を報告する
==========================

df は、ファイルシステムごとに、使用されているディスク容量と利用可能なディスクス容量を報告する。

書式:

     df [OPTION]... [FILE]...

引数を指定しないと、df は、現在マウントされているすべてのファイルシステム (ファイルシステムのタイプを問わない) について、使用されているディスク容量と、利用可能なディスク容量を報告する。引数が指定されている場合は、引数として指定された各 FILE が存在するファイルシステムについて報告する。

通常、ディスク容量は 1024 バイトを 1 単位として表示するが、この動作は変更することができる (see Block size)。なお、小数点以下は切り上げて整数にする。

bind マウントについては、引数が指定されていない場合に df が表示するのは、そのデバイスに関する統計情報のうち、ファイルシステムのリスト中で (すなわち、MTAB 中で) マウントポイントの名前が最も短いものに関する情報のみである。すなわち、-a オプションが指定されていないときは、情報が重複するエントリは表示しない。

同じ理屈で、ダミーの擬似デバイスについては、そのマウントポイントに対する別のマウントエントリが存在し、それが実在のブロックデバイスのものであり、しかもデバイス番号が同じ場合、 df は擬似デバイスのマウントエントリの方は省略する。たとえば、ブート初期に作成される擬似ファイルシステムの rootfs は、実際のルートデバイスがすでにマウントされていれば、デフォルトでは表示されない。

引数 FILE がスペシャルファイルに還元され、そのスペシャルファイル上に存在するファイルシステムが現在マウントされている場合、 df が表示するのは、そのファイルシステムの利用可能な容量であって、デバイス・ノードが存在するファイルシステムの利用可能な容量ではない。また、GNU の df は、マウントされていないファイルシステムのディスク使用量を測定しようとはしない。なぜなら、ほとんどのファイルシステムにおいて、そういうことを行うには、ファイルシステムの構造について他と全く共通性のない詳しい情報が必要だからである。

このプログラムでは以下のオプションが使用できる。参照: Common options.

-a
--all
     一覧表示に、ダミーのファイルシステム、重複するファイルシステム、アクセスできないファイルシステムも含める。そうしたものは、デフォルトでは省略されるのである。ダミーのファイルシステムというのは、/proc のような特殊用途の擬似ファイルシステムがその典型であり、ストレージと結びついていないものだ。重複するファイルシステムとは、ローカルやリモートのファイルシステムで、ローカルのファイル階層の別の場所にもマウントされているものや、bind マウントされたものである。アクセスできないファイルシステムとは、マウントされているが、その後そのマウントポイントに他のファイルシステムが二重にマウントされたものや、あるいは、マウントポイントのパーミッションなど、他の理由でアクセスできなくなっているものを言う。

-B SIZE
--block-size=SIZE
     SIZE によって単位の大きさを変更してから、サイズを表示する (see Block size)。たとえば、-BG と指定すれば、1,073,741,824 バイトを 1 単位として、サイズを表示する。

-h
--human-readable
     各サイズの後ろに、メビバイトなら M といった、大きさを示す文字を付ける。 1000 ではなく、1024 の累乗が使われるので、M は 1,048,576 バイトを表している。このオプションは、--block-size=human-readable と同じである。1000 の累乗が使いたければ、"--si オプションを使用すればよい。

-H
     --si オプションと同じである。

-i
--inodes
     ブロックの使用量ではなく、inode の使用情報を一覧表示する。 inode (index node の略称) には、ファイルの所有者、許可属性、タイムスタンプ、ディスク上の位置といった、ファイルに関する情報が含まれている。

-k
     デフォルトのブロックサイズがどうなっていようと、1 ブロック 1024 バイトでサイズを表示する (see Block size)。このオプションは --block-size=1K に等しい。

-l
--local
     一覧表示するのをローカルのファイルシステムに限定する。デフォルトでは、リモートのファイルシステムも表示される。

--no-sync
     使用量に関するデータを取得する前に sync システムコールを実行しない。そのため、多数のディスクを搭載しているシステムでは、df の実行速度が目に見えて向上するが、システムによっては (特に SunOS では)、出力結果がほんの少し古いものになるかもしれない。これがデフォルトの動作である。

--output
--output[=FIELD_LIST]
     FIELD_LIST で定義した出力フォーマットを使用する。FIELD_LIST を省略した場合は、すべてのフィールドを表示する。後者の場合、列の順序は、以下に挙げているフィールドの説明の順序と同じである。

     --output オプションは、-i, -P, -T のどのオプションとも一緒に使うことができない。

     FIELD_LIST は、df の出力に含まれることになる、コンマで区切った列のリストであり、このリストによって出力する列の順序を制御することができる。従って、各フィールドは任意の場所に置くことができるが、一度しか使うことができない。

     FIELD_LIST で使える有効なフィールドの名前は、次のものである。

     source
          マウントポイントにマウントする対象。たいていはデバイス。

     fstype
          ファイルシステムのタイプ。

     itotal
          inode の総数。

     iused
          使用 inode 数。

     iavail
          使用可能な inode 数。

     ipcent
          IUSED を ITOTAL で割ったパーセント表示。

     size
          ブロックの総数。

     used
          使用ブロック数。

     avail
          使用可能なブロック数。

     pcent
          USED を SIZE で割ったパーセント表示。

     file
          ファイル名をコマンドラインで指定した場合、そのファイル名。

     target
          マウントポイント。

     ブロックや inode の統計情報を表すフィールドは、他の場合と同じく、 -h のような数値の大きさを調整するオプションの影響を受ける。

     FIELD_LIST の定義は、複数の --output オプションを使用して、分割しても構わない。

          #!/bin/sh
          # TARGET (すなわち、マウントポイント) に続けて、そのブロックや
          # inode の使用状態をパーセントで表示する。
          df --out=target --output=pcent,ipcent

          # 表示できるすべてのフィールドを表示する。
          df --o

-P
--portability
     POSIX の出力形式を使用する。デフォルトの形式に似ているが、次の点で異なっている。

      1. 各ファイルシステムついての情報が、常にぴったり 1 行で表示され、マウントされるデバイスが、それのみで 1 行を占めることがない。そのため、マウントされるデバイスの名前の長さが 20 字を越えると (たとえば、ネットワーク・マウントの場合にそういうことがありそうだ)、各項目の列がずれることになる。

      2. ヘッダ行の項目名が、POSIX に準拠したものになる。

      3. デフォルトのブロックサイズや出力の書式が、環境変数 DF_BLOCK_SIZE, BLOCK_SIZE, BLOCKSIZE の影響を受けなくなる。とは言え、デフォルトのブロックサイズについては、 POSIXLY_CORRECT の影響だけは、やはり受ける。すなわち、 POSIXLY_CORRECT が設定されていれば、ブロックサイズは 512 バイトであり、さもなければ 1024 バイトである。 See Block size.

--si
     各サイズにの後ろに、メガバイトなら M といった、SI 形式の略号を付ける。 1024 ではなく、1000 の累乗が使用されるので、M は 1,000,000 バイトを表している。このオプションは、--block-size=si と同じことである。1024 の累乗が使いたければ、-h や --human-readable を使用すればよい。

--sync
     使用量に関するデータを取得する前に `sync' システムコールを実行する。システムによっては (特に SunOS では)、そうすることでより最近の結果が得られるが、一般的に言って、このオプションを使用すると、df の実行速度がかなり低下する。ファイルシステムをたくさんマウントしている場合や、作業が頻繁に行われているファイルシステムでは、とりわけ遅くなる。

--total
     すべての引数を処理した後で、全引数についての総計を表示する。このオプションを使用すれば、ディスクの容量、使用した量、使用可能な量について、リストされているすべてのデバイスを合わせた合計を知ることができる。引数が一つも指定されていない場合は、df は使用可能な容量の合計に無関係なファイルシステムを除外しようとして、できるだけのことをする。重複するリモート・ファイルシステムを計算に入れないといったことをするのである。

     総計の行において df は SOURCE の列に "total" と表示し、 TARGET の列に "-" という文字を表示する (訳注: SOURCE, TARGET などの列については、--output の説明を参照していただきたい)。 SOURCE の列が存在しない場合は、TARGET の列が存在すれば、 df は TARGET の列に "total" と表示する。

-t FSTYPE
--type=FSTYPE
     一覧表示するファイルシステムを FSTYPE というタイプに限定する。 -t オプションを複数回使うことによって、複数のタイプのファイルシステムを指定することができる。デフォルトでは、いかなるタイプのファイルシステムも除外しない。

-T
--print-type
     各ファイルシステムのタイプを表示する。このとき表示されるタイプは、 -t や -x オプションを使って、一覧表示に含めたり、一覧表示から除外したりできるタイプと同じものである。すなわち、表示されるタイプは何であれ、システムによってサポートされているということだ。以下に、よく見受けられるタイプの名前をいくつか挙げておく (当然ながら、ここに挙げるものがすべてではない)。

     nfs
          NFS ファイルシステム。すなわち、ネットワーク越しにほかのマシンからマウントしているファイルシステム。このタイプ名は、あらゆるシステムで共通して使われているようである。

     ext2, ext3, ext4, xfs, btrfs...
          ローカルでマウントしているハードディスクのファイルシステム。 (ローカルのマウントでは、システムが複数のタイプをサポートしていることもある。たとえば、Linux がそうだ。)

     iso9660, cdfs
          CD や DVD ドライブのファイルシステム。HP-UX は cdfs を使用し、ほかのシステムのほとんどは iso9660 を使用している。

     ntfs,fat
          MS-Windows や MS-DOS で使用されるファイルシステム。

-x FSTYPE
--exclude-type=FSTYPE
     一覧表示するファイルシステムを FSTYPE というタイプ以外のものに限定する。 -x オプションを複数回使うことによって、複数のタイプのファイルシステムを除外することができる。デフォルトでは、いかなるタイプのファイルシステムも除外しない。

-v
     無視される。System V 版の df との互換のためにある。

df がインストールされるのは、利用可能なマウントテーブルを持つシステムだけである。従って、移植を考慮したスクリプトは、その存在を当てにしない方がよい。

終了ステータス 0 は成功を示し、0 以外の値は失敗を示す。 実行に失敗しても、全く何も出力されないこともある。そういうときに、たとえば、ディレクトリ DIR が ext3 や reiserfs というタイプのファイルシステム上にあるかどうかを調べるには、 df -t ext3 -t reiserfs DIR といったコマンドを実行して、終了ステータスを検査すればよい。

ファイルシステムのタイプを判断するには、ファイルシステムのリスト (MTAB) が必要になる。従って、実行の失敗には、ファイルシステムのリストを読み込むことができないときに、ファイル名を示す引数とともに -a, -l, -t, -x といったオプションが一つ以上使われた場合が含まれる。

du: ファイルのディスク使用量を概算する
=====================

du は、指定した一連のファイルのディスク使用量を報告する。引数がディレクトリの場合は、サブディレクトリごとのディスク使用量も報告する。

書式:

     du [OPTION]... [FILE]...

引数を指定しないと、du は、カレントディレクトリのディスク使用量を報告する。通常、ディスク使用量は 1024 バイトを 1 単位として表示するが、この動作は変更することができる (see Block size)。なお、小数点以下は、切り上げて整数にする。

2 個以上のハードリンクが同一のファイルを指している場合は、そのうちの 1 個のみが計算の対象になる。引数 FILE の順番によって、どのリンクが計算の対象になるかが変わってくるので、引数の順番を変更すると、du が出力する数値や項目が変化するかもしれない。

このプログラムでは以下のオプションが使用できる。参照: Common options.

-0
--null
     各行の末尾に改行ではなく、ゼロバイト (ASCII NUL) を出力する。このオプションを使用すると、出力するデータの途中に改行が現れる場合でも、他のプログラムがその出力を解析できるようになる。

-a
--all
     ディレクトリだけでなく、すべてのファイルについて使用量を表示する。

--apparent-size
     ディスクの使用量ではなく、見かけのサイズを表示する。ファイルの見かけのサイズとは、通常ファイルに対して wc -c、あるいは、もっと普通に ls -l --block-size=1 や stat --format=%s を実行したときに返されるバイト数である。たとえば、zoo という単語を改行を付けずに書き込んだファイルなら、当然ながら、見かけのサイズは 3 になる。だが、そうした小さなファイルも、そのファイルが存在するファイルシステムのタイプと設定次第で、 0 から 16 KiB、あるいは、それ以上のディスクスペースを占有するかもしれないのだ。もっとも、穴空きファイル (sparse file) の場合は事情が別である。たとえば、

          dd bs=1 seek=2GiB if=/dev/null of=big

     上記のコマンドで作成した穴空きファイルは、見かけのサイズこそ 2 GiB だが、最近のほとんどのシステムでは、実際に使用するディスクスペースは、ほとんど 0 である。

-B SIZE
--block-size=SIZE
     SIZE によって単位の大きさを変更してから、サイズを表示する (see Block size)。たとえば、-BG と指定すれば、1,073,741,824 バイトを 1 単位として、サイズを表示する。

-b
--bytes
     --apparent-size --block-size=1 と同じ。

-c
--total
     すべての引数を処理した後で、全引数からなる総計を表示する。このオプションを使用すれば、指定したファイルやディレクトリについてディスク使用量の合計を知ることができる。

-D
--dereference-args
     コマンドラインで引数に指定されたシンボリックリンクの参照を行う。コマンドライン引数以外のシンボリックリンクには影響がない。このオプションは、/usr/tmp のような、シンボリックリンクであることが多いディレクトリのディスク使用量を調べるときに、重宝である。

-d DEPTH
--max-depth=DEPTH
     ディレクトリ階層の基点 (訳注: 要するに、コマンドラインで指定されたディレクトリ) から最大 DEPTH 段階下がったところまでにある各ディレクトリについて、ディスク使用量の合計を表示する (--all オプションが付いているときは、ファイルについても表示する)。基点自体は段階 0 なので、du --max-depth=0 は du -s と同じことになる。

--files0-from=FILE
     コマンドラインで名前を指定されたファイルの処理を行わない。その代わりに、ファイル FILE に名前が書き込まれているファイルの処理を行う。なお、FILE 中に書かれている各ファイル名は、ゼロバイト (ASCII NUL) で終端されていなければならない。このオプションは、ファイル名のリストが長すぎて、コマンドライン長の上限を超過してしまいそうなときに、便利である。そうした場合、du を xargs 経由で実行するのは、望ましくない。なぜなら、xargs はファイルのリストをいくつかの部分に分割して du に渡すので、du はリスト全体の --total (-c) オプションを使用した結果ではなく、部分リストごとの --total (-c) オプションを使用した結果を表示してしまうからである。 ASCII NUL で終端されたファイル名のリストを得る方法の一つは、 GNU find に -print0 を付けて使うことである。 FILE に - を指定すれば、 ASCII NUL で終端されたファイル名を標準入力から読み込むことができる。

-H
     --dereference-args (-D) と同じである。

-h
--human-readable
     各サイズの後ろに、メビバイトなら M といった、大きさを示す文字を付ける。 1000 ではなく、1024 の累乗が使われるので、M は 1,048,576 バイトを表している。このオプションは、--block-size=human-readable と同じである。1000 の累乗が使いたければ、"--si オプションを使用すればよい。

--inodes
     ブロックの使用状態ではなく、inode の使用状態をリストする。このオプションが役に立つのは、多くのファイルを収納しているために、ファイルシステムの inode スペースを大量に消費しているディレクトリを探すときである (df の --inodes オプションも参照すること)。このオプションは、-a, -c, -h, -l, -s, -S, -t, -x といったオプションと組み合わせて使ってもよい。しかし、ブロックサイズ関係の他のオプション、たとえば、-b, -m, --apparent-size などを渡しても、無視される。

-k
     デフォルトのブロックサイズがどうなっていようと、1 ブロック 1024 バイトでサイズを表示する (see Block size)。このオプションは --block-size=1K に等しい。

-L
--dereference
     シンボリックリンクの参照を行う (リンク自体のディスク使用量ではなく、リンクが指しているファイルやディレクトリの使用量を表示する)。

-l
--count-links
     すべてのファイルを計算に入れる。すなわち、(ハードリンクとして) 前に現れたことがあっても、計算に入れる。

-m
     デフォルトのブロックサイズを変更し、1 ブロック 1,048,576 バイトのブロック数でサイズを表示する (see Block size)。このオプションは、--block-size=1M と同じである。

-P
--no-dereference
     du が出会った各シンボリックリンクについて、シンボリック自体の使用ディスクスペースを計算する。

-S
--separate-dirs
     通常、(--summarize オプションを使用しない場合の) du の出力において、D というディレクトリ名の隣に表示されるサイズは、 D 以下にあるすべてのエントリのサイズの合計に、 D 自体のサイズを加えたものである。それに対して、--separate-dirs オプションを指定すると、D というディレクトリ名に対して報告されるサイズは、いかなるサブディレクトリのサイズも含まないものになる。

--si
     各サイズにの後ろに、メガバイトなら M といった、SI 形式の略号を付ける。 1024 ではなく、1000 の累乗が使用されるので、M は 1,000,000 バイトを表している。このオプションは、--block-size=si と同じことである。1024 の累乗が使いたければ、-h や --human-readable を使用すればよい。

-s
--summarize
     各引数についてその合計ディスク使用量のみを表示する (訳注: すなわち、引数がディレクトリの場合、そのサブディレクトリごとの情報まで表示しない)。

-t SIZE
--threshold=SIZE
     指定された SIZE を目安にして、表示する対象を取捨する。SIZE は、通常モードではディスク使用量を指し (see Block size)、--inodes オプションと組み合わせた場合は inode 使用数を指す。 (訳注: ディスク使用量の目安として使う場合、SIZE の単位は、デフォルトではバイトである。もちろん、K, M, G などの接尾辞を付けることもできる。)

     SIZE が正の数ならば、du はサイズがそれ以上である対象のみを表示する。

     SIZE が負の数ならば、du はサイズがそれ以下である対象のみを表示する。

     GNU の find を使えば、特定のサイズのファイルを見つけることができる。それに対して、du の --threshold を使うと、ディレクトリも指定サイズに基づいて篩い分けることができるのである。

     --threshold オプションは、--apparent-size オプションと組み合わせることができるのに留意していただきたい。その場合は、見かけのサイズに基づいて表示対象を絞り込むことになる。

     --threshold オプションは、--inodes オプションと組み合わせることもできる。その場合は、inode 数に基づいて表示対象を絞り込むことになる。

     200 メガバイト以上のサイズを持つディレクトリを捜すには、 --threshold オプションを次のように使えばよいだろう。

          du --threshold=200MB

     見かけのサイズが 500 バイト以下のディレクトリやファイルを捜すには (-a を使っていることに注意)、--threshold を次のように使えばよい。

          du -a -t -500 --apparent-size

     ルートファイルシステム上にあるディレクトリで、20000 以上の inode を使用しているものを、/ 以下のディレクトリ階層で捜すには、 --threshold を次のように使えばよい。

          du --inodes -x --threshold=20000 /

--time
     ディレクトリやそのサブディレクトリに存在するファイルについて表示する際に、その最終更新日時 (modification time) も表示する。

     (訳注: 一つ留意していただきたいことがある。ディレクトリのタイムスタンプについては、そのディレクトリ以下にあるファイルのうち (そのディレクトリ直下のファイルとはかぎらない)、最終更新日時がもっとも新しいファイルのタイムスタンプと同一のものが表示される。すなわち、ディレクトリのタイムスタンプは、ls -l で表示されるものとは違うことがあるわけだ。このオプションや、そのバリエーションである次の二つのオプションは、あるディレクトリ以下を最後に使用したのはいつかを知るのに便利である。)

--time=ctime
--time=status
--time=use
     ディレクトリ以下にあるファイルについて表示する際に、最終更新日時ではなく、最終ステータス変更日時 (inode 中の ctime) を表示する。

     (訳注: 原文でもこの三つのオプションを等価なものとして並べているが、訳者としては、--time=use と等価なのは、--time=ctime ではなく、 --time=atime ではないかと思う。ご自分で確かめていただきたい。)

--time=atime
--time=access
     ディレクトリ以下にあるファイルについて表示する際に、最終更新日時ではなく、最終アクセス日時 (inode 中の atime) を表示する。

--time-style=STYLE
     タイムスタンプを STYLE 形式で表示する。このオプションは、--time オプションと併せて指定したときにのみ効果がある。STYLE は以下の一つでなければならない。

     +FORMAT
          FORMAT を使って、タイムスタンプを表示する。その場合、FORMAT は、date コマンドの書式引数と同じように解釈される (see date invocation)。たとえば、--time-style="+%Y-%m-%d %H:%M:%S" と指定すると、 du の表示するタイムスタンプは、 2002-03-30 23:45:56 のようになる。date の場合と同様、 FORMAT の解釈は、LC_TIME ロケール・カテゴリの影響を受ける。

     full-iso
          タイムスタンプを省略なしで表示する。すなわち、ISO 8601 の日付、時刻、タイムゾーンという構成要素を nanosecond (10 億分の 1 秒) の精度で使用するわけだ。一例を挙げると、2002-03-30 23:45:56.477817180 -0700 といった表示になる。この形式は、+%Y-%m-%d %H:%M:%S.%N %z と同じである。

     long-iso
          ISO 8601 の日付と時刻の構成要素を分の単位まで表示する。たとえば、 2002-03-30 23:45。このタイムスタンプは、full-iso タイムスタンプより短く、日常作業にはたいてい十分である。この形式は +%Y-%m-%d %H:%M と同じである。

     iso
          タイムスタンプに ISO 8601 書式の日付を表示する。たとえば、 2002-03-30 といった具合である。この形式は、+%Y-%m-%d と同じである。

     --time-style オプションのデフォルト値は、環境変数 TIME_STYLE を使って指定することができる。 TIME_STYLE が設定されていない場合、デフォルトの形式は long-iso である。 ls と共通の TIME_STYLE を使えるようにするため、 + で始まる TIME_STYLE の値が、改行を含んでいる場合は、改行以後の文字は無視されることになる。また、TIME_STYLE の値が posix- で始まる場合、posix- は無視される。さらに、TIME_STYLE の値が locale の場合、TIME_STYLE は無視される。

-X FILE
--exclude-from=FILE
     --exclude に似ているが、除外するパターンを FILE から 1 行につき 1 パターン読み込む点が違う。FILE が - なら、パターンを標準入力から読み込む。

--exclude=PATTERN
     再帰的な処理を行っているとき、PATTERN にマッチするサブディレクトリやファイルをスキップする。たとえば、du --exclude='*.o' と指定すると、名前が .o で終わるファイルを除外することになる。

-x
--one-file-system
     処理される引数が存在するファイルシステムとは別のファイルシステムにあるディレクトリをスキップする。

BSD システムでは、HP-UX システムから NFS マウントしているファイルについて、 du は正確な値の半分のサイズを報告する。逆に、HP-UX システムでは、 BSD システムから NFS マウントしているファイルについて、du は正確な値の 2 倍のサイズを報告する。これは HP-UX にある欠陥のせいであり、 HP-UX の du プログラムも、そのとばっちりを受けているのである。

終了ステータス 0 は成功を示し、0 以外の値は失敗を示す。

stat: ファイルやファイルシステムの状態を報告する
===========================

stat は指定されたファイルに関する情報を表示する。

書式:

     stat [OPTION]... [FILE]...

オプションなしで実行すると、stat は指定されたファイルについてすべての情報を報告する。また、stat を使って、指定されたファイルが存在しているファイルシステムの情報を報告させることもできる。ファイルがリンクの場合は、リンクが指しているファイルについて情報を提供させることも可能だ。

シェルの組み込み機能の stat やエイリアスのために、 stat に何の修飾も付けずに対話的に使ったり、スクリプトの中で使ったりすると、動作がここで述べているものとは違うことがあるかもしれない。シェルによる干渉を避けるためには、env 経由で stat を起動すればよい (すなわち、env stat ... のようにだ)。

-L
--dereference
     stat がシンボリックリンクを処理する方法を変更する。このオプションを付けると、stat は、引数中の各シンボリックリンクが参照しているファイルを操作の対象にする。このオプションがないと、stat が対象にするのは、引数のシンボリックリンクそのものになる。

-f
--file-system
     指定されたファイルそのものについての情報ではなく、そのファイルが存在しているファイルシステムについての情報を報告する。このオプションを指定すると、自動的に -L オプションも指定される。

-c
--format=FORMAT
     デフォルトの書式の代わりに、FORMAT を使用する。 FORMAT の末尾には自動的に改行が付けられるので、下記のようなコマンドを 2 個以上の FILE オペランドに対して実行すると、各オペランドあたり 1 行の出力を生じることになる。

          $ stat --format=%d:%i / /usr
          2050:2
          2057:2

--printf=FORMAT
     デフォルトの書式の代わりに、FORMAT を使用する。--format に似ているが、バックスラッシュ・エスケープを解釈して変換する。また、行末に自動的に改行を付けることもしない。そこで、改行がしたければ、 FORMAT 中で \n を指定する必要がある。 --printf を使って / と /usr のデバイス番号と inode 番号を表示するには、こんなふうにする。

          $ stat --printf='%d:%i\n' / /usr
          2050:2
          2057:2

-t
--terse
     情報を簡潔な形式で表示する。他のプログラムで解析するときに都合がよい。

     下記の二つのコマンドの出力は全く同じである。また、下記の --format は、デフォルトの出力書式が (もっと詳細な形で) 表示する項目とほぼ同じものを指定している。もっとも、SELinux セキュリティ・コンテキストが有効になっている場合には、このフォーマット文字列の末尾に、もう一つ %C を付け加えることになるだろうが。

          $ stat --format="%n %s %b %f %u %g %D %i %h %t %T %X %Y %Z %W %o" ...
          $ stat --terse ...

     --file-system モードのときの簡潔形式の出力を上と同じように説明的に表現すると、

          $ stat -f --format="%n %i %l %t %s %S %b %f %a %c %d" ...
          $ stat -f --terse ...

--format や --printf の FORMAT 中で、ファイルに対して使用できる書式指定子には以下のものがある。

  * %a - 8 進数で表現したアクセス権 (printf のフラグ # と 0 に留意)

  * %A - 人間にわかりやすい形式で表現したアクセス権

  * %b - 割り当てられているブロック数 (%B を参照)

  * %B - %b の報告で使われる 1 ブロックのバイト数

  * %C - ファイルの SELinux セキュリティ・コンテキスト (取得できる場合)

  * %d - 10 進数で表現したデバイス番号

  * %D - 16 進数で表現したデバイス番号

  * %f - 16 進数で表現した Raw モード

  * %F - ファイルの種類

  * %g - 所有グループの ID 番号

  * %G - 所有グループ名

  * %h - ハードリンク数

  * %i - Inode 番号

  * %m - マウントポイント (下記の説明を参照)

  * %n - ファイル名

  * %N - 引用符で囲んだファイル名。シンボリックリンクなら、参照先も表示 (下記参照）

  * %o - I/O 転送サイズの最適値の提案

  * %s - ファイル全体の大きさ。サイズはバイト数

  * %t - 16 進数で表現したメジャー・デバイス番号 (下記参照)

  * %T - 16 進数で表現したマイナー・デバイス番号 (下記参照)

  * %u - 所有者のユーザ ID 番号

  * %U - 所有者のユーザ名

  * %w - ファイルの作成日時 (the birth time)。不明の場合は - を表示

  * %W - Unix 紀元からの秒数で表したファイルの作成日時、または 0

  * %x - 最終アクセス日時 (atime)

  * %X - Unix 紀元からの秒数で表した最終アクセス日時

  * %y - 最終データ更新日時 (mtime)

  * %Y - Unix 紀元からの秒数で表した最終データ更新日時

  * %z - 最終ステータス変更日時 (ctime)

  * %Z - Unix 紀元からの秒数で表した最終ステータス変更日時

%a という書式はファイルのモードを 8 進数で表示するので、 printf の # と 0 フラグを使って、出力の先頭のゼロ埋めをコントロールするとよい。たとえば、先頭を 0 で埋めて、表示を少なくとも 3 桁にし、それより大きい数値も、 8 進数であることをはっきりさせるには、%#03a を使えばよい。

%N の書式は、環境変数 QUOTING_STYLE によって設定することができる。その環境変数が設定されていない場合、デフォルトの値は、shell-escape である。使用できるクォーティングスタイルには、以下のものがある。

literal
     文字列に手を加えず、そのまま出力する。これは、-N や --literal オプションと同じである。

shell
     文字列にシェルのメタ文字がある場合や、出力が誤解を招くものになりそうな場合に、シェル向けのクォートを施す。このクォート方法は、bash のような POSIX 互換のシェルにはふさわしいものだが、 csh のような非互換のシェルでは、必ずしもうまく働くとはかぎらない。

shell-always
     普通ならクォートが不要な場合でも、文字列にシェル向けのクォートを施す。

shell-escape
     shell に似ているが、非表示文字のクォーティングに POSIX 提唱の $'' という書式を使用する。ほとんどのシェルに適している。 (訳注: ファイル名中に空白 (0x20) がある場合は、ファイル名全体をシングルクォートで囲む。)

shell-escape-always
     shell-escape に似ているが、普通ならクォートが不要な場合でも、文字列にクォートを施す。

c
     C 言語の文字列リテラルをクォートするときのように、文字列をクォートする。文字列をダブル・クォートで囲むことも行う。これは、-Q や --quote-name オプションと同じである。

escape
     C 言語の文字列リテラルをクォートするときのように、文字列をクォートする。ただし、文字列をダブル・クォートで囲むことはしない。これは、-b や --escape と同じである。

clocale
     C 言語の文字列リテラルをクォートするときのように、文字列をクォートする。ただし、文字列を囲む引用符には、ロケールにふさわしいものを使う。

locale
     C 言語の文字列リテラルをクォートするときのように、文字列をクォートする。ただし、文字列を囲む引用符には、ロケールにふさわしいものを使い、さらに、デフォルトの C ロケールで言うと、"like this" ではなく、 'like this' のようにクォートを行う。この方が見栄えのよいディスプレイが多い。

%t や %T という書式指定子は、stat(2) 構造体の st_rdev メンバに対応するものであり、従って、キャラクタ・スペシャルファイルやブロック・スペシャルファイルに対してしか動作が定義されていない。システムやファイルタイプによっては、st_rdev が他のものを表現するために使われていることもありえる。

%W, %X, %Y, %Z では、ピリオドに続けて精度を書くことで、小数点以下何桁まで表示するかを指定することができる。たとえば、%.3X と指定すると、最終アクセス日時がミリ秒の精度で出力される。ピリオドだけ指定して、精度を省略すると、stat は 9 桁を使用する。従って、 %.X は %.9X と同じことになるわけだ。なお、余分な精度を捨てる際、タイムスタンプは負の無限大方向に切り下げられる (訳注: 平たく言うと、タイムスタンプのような正の数値の場合、指定された桁数より下の部分は切り捨てられるということ。以下の例を参照)。

     0 で埋める:
       $ stat -c '[%015Y]' /usr
       [000001288929712]
     スペースで位置を揃える:
       $ stat -c '[%15Y]' /usr
       [     1288929712]
       $ stat -c '[%-15Y]' /usr
       [1288929712     ]
     精度指定:
       $ stat -c '[%.3Y]' /usr
       [1288929712.114]
       $ stat -c '[%.Y]' /usr
       [1288929712.114951834]

%m によって表示されるマウントポイントは、df によるマウントポイントの出力とほぼ同じである。ただし、以下の点で異なっている。

  * stat はデフォルトでは、シムリンクの参照を行わない (そのためには、-L を指定する必要がある)。

  * 引数としてデバイスノードが指定された場合、 stat はファイルシステムのリスト中にそのノードを捜し求めたりはせず、デバイスノードそのものを動作の対象にする (訳注: すなわち、そのデバイス上に存在するファイルシステムのマウントポイントではなく、デバイスノードそのもののマウントポイントを表示する)。

  * bind マウントされているファイルについては、 stat はそのファイルが載っているデバイスの最初のマウントポイントではなく、 bind マウントで指定された別名 (訳注: 原文は alias。mount --bind olddir newdir における newdir のことか) の方を出力する。出力に変化がなくなるまで、再帰的に stat を呼び出せば、現在ベースになっているマウントポイントを知ることができる。

     (訳注: 訳者には意味不明。「現在ベースになっているマウントポイント (the current base mount point)」が、上記訳注の newdir のことなら、 stat を再帰的に呼び出すまでもない。stat -c "%m" newdir/FILE は、 newdir を表示する。また the current base mount point が「根底にある (すなわち、デバイスを最初にマウントした) マウントポイント」のことなら、 stat を再帰的に呼び出しても、それを突き止めることはできない。ひょっとすると、書式指定子に %m が追加された coreutils-8.6 から coreutils-8.20 あたりまでの stat を linux-2.6 時代の古いカーネルと組み合わせて使ったときの動作を言っているのかもしれない。その場合は、stat -c "%m" newdir/FILE は上記の olddir を出力するようだ。従って、そうした組み合わせでは、stat を再帰的に実行することで、最初にデバイスをマウントしたときのマウントポイントを知ることができる。)

ファイルシステムの情報をリストする際には (すなわち、--file-system (-f) 使用時には)、書式指定子の別の一群を使わなければならない。

  * %a - スーパーユーザ以外にも利用できる未使用ブロック数

  * %b - ファイルシステムの総データブロック数。

  * %c - ファイルシステムの総 inode 数

  * %d - ファイルシステムの未使用 inode 数

  * %f - ファイルシステムの未使用ブロック数

  * %i - 16 進数で表現したファイルシステム ID

  * %l - ファイル名の最大長

  * %n - ファイル名

  * %s - ブロックサイズ (高速転送用)

  * %S - 基本ブロックサイズ (ブロック計算用)

  * %t - 16 進数で表現したファイルシステムのタイプ

  * %T - 人間にわかりやすい形式で表現したファイルシステムのタイプ

タイムスタンプは、タイムゾーンのルールに従って表示されるが、そのルールを指定しているのは、環境変数 TZ である。 TZ が設定されていない場合は、システムのデフォルトのルールに従って表示される。 See Specifying the Time Zone with TZ (The GNU C Library Reference Manual).

終了ステータス 0 は成功を示し、0 以外の値は失敗を示す。

sync: キャッシュされた書き込みを永続的な記憶装置に同期する
================================

sync は、メモリ中のファイルやファイルシステムを永続的な記憶装置に同期する。

書式:

     sync [OPTION] [FILE]...

sync は、メモリ中にバッファされているデータがあれば、それをディスクに書き出す。そうした書き出しには、スーパーブロックの変更、inode の変更、遅延読み書きを含むことができる (が、それだけに止まらない)。この機能はカーネルによって実装されていなければならない。sync プログラムは、システムコールの sync, syncfs, fsync, fdatasync を実行する以外、何もしないのである。

カーネルは、(比較的遅い) ディスクの読み書きをできるだけしないで済ますために、メモリにデータを保持している。このことによって、動作速度が向上するが、コンピュータがクラッシュした場合、データが失われたり、ファイルシステムが壊れたりという結果が生じかねない。sync コマンドは、カーネルに命じて、メモリ上にあるデータを永続的な記憶装置に書き出させるのである。

引数を指定すると、デフォルトでは指定されたファイルのみが fsync(2) システムコールを使って同期されることになる。

1 個以上のファイルを指定した場合は、以下のオプションを使って同期方法を変更することができる。使用できるオプションについては、次の章も参照していただきたい。 Common options.

-d
--data
     fdatasync(2) を使用して、ファイルのデータと、ファイルシステムの整合性を維持するのに必要なメタデータのみを同期する。

-f
--file-system
     指定したファイルが存在するファイルシステムに対して I/O 待ちになっているすべてのデータを syncfs(2) システムコールを使用して、同期する。注意していただきたいが、たとえば /dev/sda といったデバイスノードを引数として渡すときは、このオプションを普通は指定しないはずである。そんなことをすると、/dev/sda で参照されるファイルシステムではなく、デバイスノードが存在するファイルシステムの同期が行われてしまうからだ。また、システムによっては、個々のデバイスノードやファイルを引数として渡すのと、全く引数を使用しないのとでは、同期のあり方が違うかもしれないことにも気をつけていただきたい。すなわち、fsync(2) に渡される引数がある場合は、書き込みバリア (write barrier) が使われることによって、引数を指定しなかったときに使用されるグローバルな sync(2) よりも、より確実な保証をもたらすかもしれないのである。

終了ステータス 0 は成功を示し、0 以外の値は失敗を示す。

truncate: ファイルサイズの短縮・伸長を行う
==========================

truncate は、各 FILE のサイズを指定したサイズにまで短縮したり、引き伸ばしたりする。

書式:

     truncate OPTION... FILE...

FILE が存在していないときは、作成する。

FILE が指定したサイズより大きい場合は、データのサイズを越える部分は失われる。 FILE が指定したサイズより小さい場合は、ファイルは引き伸ばされ、引き伸ばされた部分は、ゼロバイト (ASCII NUL) の連続に見えるようになる (引き伸ばされた部分は、穴空きファイル (sparse file) の穴になる)。

このプログラムでは以下のオプションが使用できる。参照: Common options.

-c
--no-create
     ファイルが存在しない場合は、作成しない。

-o
--io-blocks
     SIZE をバイト数ではなく、FILE を構成する I/O ブロック数と見なす。

-r RFILE
--reference=RFILE
     RFILE のサイズを基準に、各 FILE のサイズを揃える。

-s SIZE
--size=SIZE
     各 FILE のサイズを SIZE にする。--io-blocks が指定されていない場合、SIZE はバイト数である。 SIZE は、整数であり、以下に挙げるような何倍かを示す接尾辞を後ろに付けることもできる。接尾辞だけ指定してもよい (訳注: その場合は、1 が前にあるものと見なされる)。

          KB =>           1000 (KiloBytes)
          K  =>           1024 (KibiBytes)
          MB =>      1000*1000 (MegaBytes)
          M  =>      1024*1024 (MebiBytes)
          GB => 1000*1000*1000 (GigaBytes)
          G  => 1024*1024*1024 (GibiBytes)

     T, P, E, Z, Y についても同様。

     SIZE の前に以下の記号の一つを置くと、現在のサイズを元にして、各 FILE のサイズを調節することができる。

          +  => SIZE だけ増やす
          -  => SIZE だけ減らす
          <  => 最大でも SIZE までにする
          >  => 最小でも SIZE はあるようにする
          /  => SIZE の倍数に切り下げる
          %  => SIZE の倍数に切り上げる

終了ステータス 0 は成功を示し、0 以外の値は失敗を示す。

テキストの表示
*******

この章では、テキスト文字列を表示するコマンドについて説明する。

echo: テキストを 1 行表示する
===================

echo は、指定された STRING を標準出力に書き出す。その際、各 STRING の間に 1 個のスペースを置き、行末に改行を付け加える。

書式:

     echo [OPTION]... [STRING]...

シェルの組み込み機能の echo やエイリアスのために、 echo に何の修飾も付けずに対話的に使ったり、スクリプトの中で使ったりすると、動作がここで述べているものとは違うことがあるかもしれない。シェルによる干渉を避けるためには、env 経由で echo を起動すればよい (すなわち、env echo ... のようにだ)。

このプログラムでは、以下のオプションが使える。参照: Common options. オプションはオペランドの前に置かなければならない。また、通常は特別な引数として使われる -- は、特別な意味を持たず、他のいかなる STRING とも同じように扱われる。

-n
     出力の末尾に改行を付けない。

-e
     各 "STRING の中に以下に挙げるバックスラッシュでエスケープした文字があると、それを解釈して変換する。

     \a
          警告 (ベル)

     \b
          バックスペース

     \c
          この位置より後を出力しない

     \e
          エスケープ

     \f
          フォームフィード (form feed)

     \n
          改行 (newline)

     \r
          復帰 (carriage return)

     \t
          水平タブ

     \v
          垂直タブ

     \\
          バックスラッシュ

     \0NNN
          8 進数 NNN (0 桁から 3 桁までの 8 進数) で表される 8 ビットの値に対応する文字。NNN が 9 ビットの値だと、9 ビット目 (最上位ビット) は無視される。

     \NNN
          8 進数 NNN (1 桁から 3 桁までの 8 進数) で表される 8 ビットの値に対応する文字。NNN が 9 ビットの値だと、9 ビット目 (最上位ビット) は無視される。

     \xHH
          16 進数 HH (1 または 2 桁の 16 進数) で表される 8 ビットの値に対応する文字。

-E
     各 STRING の中にあるバックスラッシュ・エスケープの解釈をしない。これがデフォルトである。-e と -E の両方が指定されている場合は、後で指定した方が効果を持つ。

環境変数 POSIXLY_CORRECT が指定されている場合に、echo の最初の引数が (単独の) -n 以外だと、echo はそうした引数をオプションとして扱わずに、形がオプションに似た引数として出力する。たとえば、echo -ne hello は、単なる hello ではなく、-ne hello を出力する。

POSIX では、いかなるオプションのサポートも要求していない。また、 POSIX では、STRING がバックスラッシュを含む場合や、最初の引数が -n の場合に、echo がどう振る舞うかは、実装側で決めることになっている。従って、他のシステムで使うことも考慮したプログラムで、行末の改行を省略したり、制御文字やバックスラッシュ・エスケープを出力したりする必要があるのならば、 echo の代わりに printf コマンドを使用することを考えてもよい。 See printf invocation.

終了ステータス 0 は成功を示し、0 以外の値は失敗を示す。

printf: データを整形して表示する
====================

printf は、テキストを整形して表示する。

書式:

     printf FORMAT [ARGUMENT]...

printf は、文字列 FORMAT を表示する。その際、C の printf 関数とほとんど同じやり方で、% 書式指定子と \ エスケープシーケンスを解釈して、数値や文字列の引数 (上記書式の ARGUMENT) を整形する。詳細については、次の項目を参照すること。 See printf format directives (The GNU C Library Reference Manual). C の関数との相違点については、以下の箇条書きのとおりである。

シェルの組み込み機能の printf やエイリアスのために、 printf に何の修飾も付けずに対話的に使ったり、スクリプトの中で使ったりすると、動作がここで述べているものとは違うことがあるかもしれない。シェルによる干渉を避けるためには、env 経由で printf を起動すればよい (すなわち、env printf ... のようにだ)。

  * FORMAT 引数は、指定された ARGUMENT のすべてを変換するのに必要なだけ、繰り返し使用される。たとえば、printf %s a b というコマンドは、ab を出力する。

  * ARGUMENT の指定がない場合は、文脈が文字列と数値のどちらを期待しているかによって、空文字列、または 0 を指定したものと見なされる。たとえば、printf %sx%d というコマンドは、x0 を表示する。

  * \c というエスケープシーケンスが追加されている。\c より後の部分を、 printf は出力しない。たとえば、printf 'A%sC\cD%sF' B E というコマンドは、ABC を表示する。

  * 16 進数エスケープシーケンス \xHH は、最大でも 2 桁である。桁数に制限のない C と、その点が違う。たとえば、printf '\x07e' というコマンドは、2 バイトを表示するが (訳注: \x07 (ベル) と e)、 C の printf ("\x07e") という文の方は、1 バイトしか表示しない。

  * 追加された書式指定子 %b は、対応する引数文字列中に \ エスケープシーケンスがある場合、それを FORMAT 文字列中にあるときと同じように解釈・変換して、引数文字列を表示する。ただし、引数中の 8 進数エスケープシーケンスは \0OOO の形を取る。 OOO は 0 から 3 桁の 8 進数である。\OOO が 9 ビットの値ならば、9 ビット目 (訳注: すなわち最上位ビット) は無視される。 %b に精度も指定すると、変換した文字列の先頭から何バイトを表示するかが、それによって決まる。

  * 追加された書式指定子 %q は、対応する引数文字列を、たいていのシェルで入力として再利用できる形で表示する。非表示文字は POSIX が提唱している $'' の書式でエスケープされ、シェルのメタ文字は適切にクォートされる。これは、ls --quoting=shell-escape の出力と同じ書式である。

  * 数値の引数は、単独の C の定数でなければならない。前に + や - が付いていてもよい。たとえば、printf %.4d -3 は、-0003 を出力する。

  * 数値が期待される引数の先頭文字が " や ' である場合、その引数の値は、引用符の直後に来る文字の数値である (訳注: すなわち、一般には、その文字の ASCII コードが出力される)。その後にさらに文字が続く場合は、環境変数 POSIXLY_CORRECT が設定されていれば、ただ単に無視され、設定されていなければ、警告が出される。一例を挙げておくと、printf "%d" "'a" は、ASCII 文字セットを使用しているホストでは、97 を出力する。 ASCII における a の数値は、10 進数表記で 97 だからだ。

引数が浮動小数点数の場合は、小数部の前にはピリオドを置かなければならない。ただし、表示は、現在のロケールの LC_NUMERIC カテゴリのルールに合わせたものになる。たとえば、小数点を表す文字がコンマのロケールでは、printf %g 3.14 というコマンドは、3,14 を出力するが、printf %g 3,14 というコマンドはエラーになる。 See Floating point.

printf は、FORMAT 中の \OOO を (OOO が 1 から 3 桁の 8 進数ならば) 表示すべき 1 バイトを指定している 8 進数と見なす。また、\xHH を (HH が 1 から 2 桁の 16 進数ならば) 表示すべき 1 文字を指定している 16 進数だと解釈する。ただし、注意していただきたいが、\OOO が 255 より大きな 10 進数に相当するときは、printf は 9 ビット目を無視する。従って、たとえば、printf '\400' は printf '\0' と同じである。

printf は、ISO C 99 で導入された 2 種類のキャラクタ・シンタクス (訳注: ここでは、コードポイントによる文字の指定法) を解釈することができる。一つは、Unicode (ISO/IEC 10646) の文字を 16 ビットで表すための \u であり、4 桁の 16 進数 HHHH で指定する。もう一つは、Unicode の文字を 32 ビットで表すための \U で、こちらは 8 桁の 16 進数 HHHHHHHH で指定する。printf は Unicode の文字を出力するに当たって、 LC_CTYPE のロケールに従う。なお、U+0000...U+009F と U+D800...U+DFFF の範囲にある Unicode の文字は、U+0024 ($), U+0040 (@), U+0060 (`) を除いて、このシンタクスでは指定することができない。

\u や \U を処理するには、フル装備の iconv の能力が必要である。 glibc 2.2 以降を採用しているシステムでは、そうした能力は使えるようになっている。 coreutils パッケージをインストールする前に、libiconv をインストールしている場合も同様だ。どちらにも当てはまらない場合は、\u や \U は、変換されずに、そのままの形で表示される。

オプションとして指定できるのは、単独の --help か --version だけである。 See Common options.  オプションはオペランドの前に置かなければならない。

Unicode のキャラクタ・シンタクスを使えば、ロケールに縛られないやり方で文字列が書けて、便利である。たとえば、次のようにすれば、

     $ env printf '\u20AC 14.95'

ユーロ通貨記号を含む文字列が、ユーロ記号をサポートするすべてのロケール (ISO-8859-15, UTF-8 など) で正しく出力されることになる。同様に、

     $ env printf '\u4e2d\u6587'

とすれば、漢字の文字列が、すべての中国語のロケール (GB2312, BIG5, UTF-8 など) で正しく表示される。

上記の例では、printf コマンドを env 経由で呼び出していることに注目していただきたい。これは、シェルのエイリアスや組み込み関数ではなく、シェルのサーチパスを使って見つけたプログラムを、確実に実行するためである。

文字列がもっと長い場合でも、各文字に対応する 16 進数コードを一つ一つ捜す必要はない。 ASCII 文字に \u エスケープ・シーケンスを混ぜる書き方は、JAVA のソースファイルで使用されるエンコーディング (JAVA source file encoding) としても知られているが、GNU の recode コマンド 3.5c 以降を使用すれば、任意の文字列をこのエンコーディングに変換することができるのだ。以下に示すのは、1 個の短文を、ロケールの如何に縛られずにその短文を出力するシェルスクリプトに変換する方法である。

     $ LC_CTYPE=zh_TW.big5 /usr/local/bin/printf \
         '\u4e2d\u6587\n' > sample.txt
       #
       # 訳注: もちろん、漢字入力の可能な LANG=zh_TW.big5 (あるいは、
       #       ja_JP.eucJP や ja_JP.utf8) の環境なら、コマンドラインで
       #       直接 printf '中文\n' と打ち込んでもよい。その方が、
       #       「各文字に対応する 16 進数コードを一つ一つ捜す必要はない」
       #       という上記の説明に、例としてはふさわしいだろう。
       #       LANG=ja_JP.eucJP の場合、下のコマンドは、当然ながら、
       #       recode eucJP..JAVA になる。LANG=ja_JP.utf8 なら、
       #       recode UTF8..JAVA だ。
       #
     $ recode BIG5..JAVA < sample.txt \
         | sed -e "s|^|/usr/local/bin/printf '|" -e "s|$|\\\\n'|" \
         > sample.sh

終了ステータス 0 は成功を示し、0 以外の値は失敗を示す。

yes: 中断されるまで文字列を表示する
====================

yes は、コマンドラインで指定された引数を、空白で区切り、末尾に改行を付けて、意図的に中断されるまで (訳注: たとえば CTRL-C で中断されるまで) 延々と表示する。引数が指定されていない場合は、y の後ろに改行を付けて、中断されるまで延々と表示する。

書き込みエラーがあると、yes はステータス 1 で終了する。

指定できるオプションは、単独の --help か --version だけである。 - で始まる引数を出力するには、その引数の前に -- を置けばよい。たとえば、yes -- --help というようにだ。See Common options.

条件
**

この章で説明するのは、その出力よりも終了ステータスの方が主として役に立つコマンドである。従って、こうしたコマンドは、シェルの if 文の条件として、あるいは、パイプラインの最後のコマンドとして使用されることが多い。

false: 何もせず、実行失敗のステータスを返す
=========================

false は、実行に失敗したこと (failure) を示す終了ステータス 1 を返す以外、何もしない。従って、シェルスクリプト中の、実行に失敗するコマンドが必要な場所で、仮のコマンドとして使用することができる。最近のほとんどのシェルでは、false は組み込みコマンドになっているので、スクリプト中で false を使う際に使用しているのは、ここで説明している false ではなく、たぶん組み込みコマンドの方である。

false は、--help と --version オプションを認識する。

このバージョンの false は、C のプログラムとして実装されている。従って、シェルスクリプトによる実装より安全かつ高速であり、アカウントを無効化するための安全なダミー・シェルとして使用することができる。

注意していただきたいが、false は、--help や --version を付けて実行した場合でも (このマニュアルで説明している他のすべてのプログラムとは違って)、実行失敗のステータスで終了する。

移植を考慮したプログラムでは、false の終了ステータスを 1 だと決めてかからない方がよい。GNU 以外のホストでは、終了ステータスが 1 より大きいこともあるからだ。

true: 何もせず、正常終了する
=================

true は、実行に成功したこと (success) を示す終了ステータス 0 を返す以外、何もしない。従って、シェルスクリプト中の、実行に成功するコマンドが必要な場所で、仮のコマンドとして使用することができる。とは言え、シェルの組み込みコマンド : (コロン) の方が、同じことをより高速に実行してくれるかもしれない。最近のほとんどのシェルでは、true は組み込みコマンドになっているので、スクリプト中で true を使う際に使用しているのは、ここで説明している true ではなく、たぶん組み込みコマンドの方である。

true は、--help と --version オプションを認識する。

もっとも、true を 0 以外のステータスで終了させることも可能だということも、心に留めておいていただきたい。--help や --version を使用したとき、標準出力がすでにクローズされていたり、 I/O エラーを引き起こすようなファイルにリダイレクトしたりすると、そういうことが起きる。たとえば、Bourne 互換のシェルを使用して、次のようにするときだ。

     $ ./true --version >&-
     ./true: write error: Bad file number
     $ ./true --version > /dev/full
     ./true: write error: No space left on device

このバージョンの true は、C のプログラムとして実装されている。従って、シェルスクリプトによる実装より安全かつ高速であり、アカウントを無効化するための安全なダミー・シェルとして使用することができる。

test: ファイルタイプのチェックや値の比較を行う
==========================

test は、条件式 EXPRESSION の評価次第で、0 (真) または 1 (偽) のステータスを返す。式を構成する各部分は、独立した引数でなければならない。

test は、ファイルのステータスを検査することができる。また、文字列を扱う演算子や、数値を比較するための演算子も備えている。

test には、test で始める書式のほかに、一対の角カッコを使用するもう一つの書式がある。たとえば、test -d / の代わりに、[ -d / ] と書いてもよい。角カッコは、独立した引数でなければならない (訳注: すなわち、他の引数と空白で分離されていなければならない)。だから、たとえば、[-d /] では、望みの結果を得られないことになる。 test EXPRESSION と [ EXPRESSION ] は、同じ意味なので、以下では前者の書式についてのみ解説する。

書式:

     test EXPRESSION
     test
     [ EXPRESSION ]
     [ ]
     [ OPTION

シェルの組み込み機能の test やエイリアスのために、 test に何の修飾も付けずに対話的に使ったり、スクリプトの中で使ったりすると、動作がここで述べているものとは違うことがあるかもしれない。シェルによる干渉を避けるためには、env 経由で test を起動すればよい (すなわち、env test ... のようにだ)。

EXPRESSION を省略した場合、test は、偽を返す。 EXPRESSION が引数 1 個だけだった場合、test は、その引数が空 (null) ならば、偽を返し、さもなければ、真を返す。引数には、-d, -1, --, --help, --version といった、他のほとんどのプログラムでなら、オプションとして扱われるものも含めて、どんな文字列でも指定することができる。そこで、ヘルプやバージョン情報を取得するには、 [ --help や [ --version という形でコマンドを実行する必要がある。この場合、いつもと違って、閉じカッコは付けない。 See Common options.

終了ステータス:

     0: 式が真の場合。
     1: 式が偽の場合。
     2: エラーが起きた場合。

ファイルタイプのテスト
-----------

以下のオプションは、ある特定のファイルタイプか否かの検査を行う。 (Unix では、あらゆるものがファイルだ。だが、ファイルならみんな同じだというわけではない！)

-b FILE
     FILE が存在し、ブロック・スペシャルデバイスならば、真。

-c FILE
     FILE が存在し、キャラクタ・スペシャルデバイスならば、真。

-d FILE
     FILE が存在し、ディレクトリならば、真。

-f FILE
     FILE が存在し、通常ファイルならば、真。

-h FILE
-L FILE
     FILE が存在し、シンボリックリンクならば、真。ファイル関係の他のすべてのテストとは違って、このテストでは、FILE がシンボリックリンクの場合、リンクの参照を行わない。

-p FILE
     FILE が存在し、名前付きパイプならば、真。

-S FILE
     FILE が存在し、ソケットならば、真。

-t FD
     FD が端末と結びついているファイルディスクリプタならば、真。

アクセス許可のテスト
----------

以下のオプションは、特定のアクセス許可について検査をする。

-g FILE
     FILE が存在し、set-group-ID ビットが立っていれば、真。

-k FILE
     FILE が存在し、sticky ビットが立っていれば、真

-r FILE
     FILE が存在し、読み出しが許可されていれば、真。

-u FILE
     FILE が存在し、set-user-ID ビットが立っていれば、真。

-w FILE
     FILE が存在し、書き込みが許可されていれば、真。

-x FILE
     FILE が存在し、実行が許可されていれば (ディレクトリの場合は、検索が許可されていれば)、真。

-O FILE
     FILE が存在し、その所有者が test コマンド実行者の実効ユーザ ID と同じならば、真。

-G FILE
     FILE が存在し、そのグループが test コマンド実行者の実効グループ ID と同じならば、真。

ファイル特性のテスト
----------

以下のオプションは、ファイルの他の特性を検査する。

-e FILE
     FILE が存在すれば、真。

-s FILE
     FILE が存在し、サイズが 0 よりも大きければ、真。

FILE1 -nt FILE2
     FILE1 が FILE2 より (更新日時 (modification date) で比較して) 新しいか、あるいは、FILE1 が存在して、FILE2 が存在しなければ、真。

FILE1 -ot FILE2
     FILE1 が FILE2 より (更新日時で比較して) 古いか、あるいは、FILE2 が存在して、FILE1 が存在しなければ、真。

FILE1 -ef FILE2
     FILE1 と FILE2 が同じデバイス番号と同じ inode 番号を持っていれば、言い換えれば、両者が互いのハードリンクならば、真。

文字列のテスト
-------

以下のオプションは、文字列の特性を検査する。シェルに対して引数 STRING を引用符で保護する必要があるかもしれない。たとえば、こんなふうにだ。

     test -n "$V"

こうした引用符は、$V が空だったり、特殊文字を含んでいたりする場合に、意図に反した引数が test に渡ることを防いでいる。

-z STRING
     STRING の長さが 0 ならば、真。

-n STRING
STRING
     STRING の長さが 0 でなければ、真。

STRING1 = STRING2
     両文字列が等しければ、真。

STRING1 == STRING2
     両文字列が等しければ、真 (= と同じ意味)。

STRING1 != STRING2
     両文字列が等しくなければ、真。

数値のテスト
------

数値間の関係を調べる演算子を挙げる。引数は、数字のみで表現される整数か (負数も使用できる)、-l STRING という特別な式でなければならない。後者は STRING の長さとして評価される。

(訳注: 要するに、普通は 10 進数の整数を引数として取るということ。 expr コマンドとは違って、test では +2 といった表現も可能だ。)

ARG1 -eq ARG2
ARG1 -ne ARG2
ARG1 -lt ARG2
ARG1 -le ARG2
ARG1 -gt ARG2
ARG1 -ge ARG2
     こうした二項算術演算子は、それぞれ次の場合に真を返す。上から順に、 ARG1 が ARG2 と比べて、等しい場合、等しくない場合、より小さい場合、より小さいか等しい場合、より大きい場合、より大きいか等しい場合。

例を挙げる。

     test -1 -gt -2 && echo yes
     => yes
     test -l abc -gt 1 && echo yes
     => yes
     test 0x100 -eq 1
     error--> test: integer expression expected before -eq

test の論理結合演算子
-------------

test 内蔵のこうした論理結合演算子より、シェルの論理基本演算子を使用した方がよいことに留意していただきたい。と言うのは、式が、パラメータの展開によっては、曖昧になることがあるからである。

たとえば、次の式は、$1 が '!' であり、$2 が空文字列 '' だと、曖昧になる (訳注: '!' が文字列か否定演算子か、曖昧だということだろう)。

     test "$1" -a "$2"

だから、以下のように書いた方がよい。

     test "$1" && test "$2"

シェルの論理基本演算子では、作業の簡略化による利益も得られる。それは、ファイルの属性のテストを何度もやる場合には、かなりのものになるかもしれない。

! EXPR
     EXPR が偽ならば、真。! は EXPR のどの部分よりも優先順位が低い。 ! は二項式の左に指定する必要があることに注意していただきたい。すなわち、1 '!' -gt 2 ではなく、'!' 1 -gt 2 である。なお、! はシェルの特殊文字であることが多いので、クォートした方が間違いがない。

EXPR1 -a EXPR2
     EXPR1 と EXPR2 の両方が真ならば、真。 -a は左結合であり、-o よりも優先順位が高い。

EXPR1 -o EXPR2
     EXPR1 と EXPR2 のどちらかが真ならば、真。 -o は左結合である。

expr: 式を評価する
============

expr は、式を評価して、結果を標準出力に書き出す。式の各構成要素 (token) は、独立した引数でなければならない。

オペランド (演算対象) は、整数か文字列である。整数は、1 個以上の 10 進数の数字から構成され、先頭に - が付いていてもよい。expr は、オペランドの位置にあるものが何であれ、それを整数、または、文字列に変換する。どちらになるかは、それに対して行われる演算次第である。

expr そのものに対しては、文字列をクォートする必要がない。だが、シェルにとって特別な意味がある、たとえば空白のような文字を保護するためには、文字列を引用符で囲むなどの方法でクォートする必要があるかもしれない。とは言え、クォートされているかどうかに関わりなく、文字列のオペランドは、丸カッコ 1 個であってはならないし、+ のような expr の演算子の一つであるべきでもない。すなわち、シェルに対してクォートするだけでは、エラーを引き起こすことなく、任意の文字列 $str を expr に渡すことはできないのだ。この問題を回避する方法の一つは、GNU の拡張である + 演算子 (訳注: この + は、算術演算子の + ではなく、直後に来る引数が文字列であることを示す文字列演算子である) を使用することだ (たとえば、+ "$str" = foo といった具合に)。もっと移植性のある方法は、 " $str" という先頭に空白を入れた表現を使用し、式の残りの部分でもそれに合わせて、先頭のスペースを考慮に入れるようにすることである (たとえば、" $str" = " foo" のように)。

負の整数や、- で始まる文字列を expr の 1 番目の引数として渡すべきではない。オプションと間違われかねないからだ。それを避けるためには、カッコでくくればよい (訳注: たとえば、 expr \( -1 + 1 \))。また、移植を考慮したスクリプトでは、文字列のオペランドに、形が整数と同じになってしまうものを使うべきではない。こちらは、先頭にスペースを入れる上記の方法で回避できる。

演算子には、記号としてオペランドとオペランドの間に置くものもあれば、キーワードとしてオペランドの前に付けるものもある。丸カッコは、おなじみのやり方で、グループ化に使用できる。ただし、丸カッコや、演算子の多くは、シェルによって評価されないように、クォートしなければならない。

GNU MP ライブラリ対応でビルドされた場合、expr は任意精度演算を使用する。そうでない場合は、ネイティブな算術型を使用するので、算術オーバーフローのために実行に失敗することがあるかもしれない。

指定できるオプションは、--help と --version だけである。 See Common options.  オプションはオペランドの前に置かなければならない。

終了ステータス:

     0: 式が null でも 0 でもない場合。
     1: 式が null または 0 の場合。
     2: 式が無効な場合。
     3: 内部エラーが起きた場合 (例: 算術オーバーフロー)。

文字列式
----

expr は、パターンマッチなどの文字列演算子をサポートしている。文字列演算子の優先順位は、算術演算子や関係演算子よりも高い (算術/関係演算子については後述する)。

STRING : REGEX
     パターンマッチを行う。まず、左右の項を文字列に変換し、右項を、先頭に ^ が暗黙のうちに付いている正規表現と見なす (grep 風の基本正規表現)。それから、その正規表現と左項がマッチするかどうかを調べる。

     マッチが成功した場合、REGEX 中でカッコ (\( と \)) を使用していれば、: 演算子は、そのカッコ内の部分表現にマッチした STRING 中の部分文字列を返す。カッコを使っていなければ、返すのはマッチした文字数である。

     マッチに失敗した場合、: 演算子は、REGEX 中でカッコ (\( と \)) を使用していれば、空文字列を、さもなければ、0 を返す。

     最初の \( ... \) のペアだけが、返り値に関係する。二番目以降のカッコのペアには、正規表現の演算子をグループ化する働きしかない。

     正規表現では、\+, \?, \| は演算子であり、それぞれ、 1 個以上にマッチする、あってもなくてもよい、候補のうちのどちらか、を意味している。ところが、SunOS などの expr では、こうした記号を通常の文字として扱っている (POSIX は、どちらの動作も認めている)。正規表現の文法については次のものが詳しい。 See Regular Expression Library (Regex). 実例をいくつか、「expr の使用例」に挙げておいた。 Examples of expr.

match STRING REGEX
     パターンマッチを行う別の方法。これは、STRING : REGEX と同じである。

substr STRING POSITION LENGTH
     STRING の部分文字列を返す。部分文字列は、POSITION の位置から始まり、最長でも LENGTH の長さである。POSITION と LENGTH のどちらかが、負数や 0 だったり、数値以外だったりする場合は、空文字列を返す。

index STRING CHARSET
     CHARSET 中の文字が最初に見つかった STRING 中の位置を返す。 STRING 中に CHARSET 中のどの文字も見つからなかった場合は、0 を返す。

length STRING
     STRING の長さを返す。

+ TOKEN
     たとえ、TOKEN が match のようなキーワードや、 / のような演算子であっても、TOKEN を文字列として解釈する。これを使用すると、expr length + "$x" や expr + "$x" : '.*/\(.\)' を実行したとき、$x の値が (たとえば) たまたま / や index であっても、適切な動作をさせることができる。この演算子は、GNU の拡張である。移植を考慮したシェルスクリプトでは、 + "$token" ではなく、" $token" : ' \(.*\)' を使うべきである。

expr にキーワードを文字列として解釈させるためには、クォート演算子 (訳注: 上で述べている + 演算子) を使用しなければならない。

数式
--

expr は、以下に挙げる通常の算術演算子を、昇順の優先順位で、サポートしている。こうした算術演算子は、前節で述べた文字列演算子より優先順位が低く、次節で述べる関係演算子より優先順位が高い。

+ -
     加算と減算。左右の項は両方とも整数に変換される。整数に変換できない場合は、エラーになる。

* / %
     乗算、除算、剰余演算。左右の項は両方とも整数に変換される。整数に変換できない場合は、エラーになる。

expr の関係表現
----------

expr は、通常の論理結合や関係表現をサポートしている。そうした演算子は、前の節で述べた文字列演算子や算術演算子より優先順位が低い。論理結合や関係表現の演算子を、優先順位の低いものから高いものへ順に並べておく。

|
     左項が null でも 0 でもなければ、左項を返す。左項が null または 0 の場合は、右項が null でも 0 でもなければ、右項を返す。両項とも null または 0 の場合は、0 を返す。左項が null でも 0 でもない場合、右項の評価は行われない。

&
     両項とも null でも 0 でもなければ、左項を返し、それ以外の場合は、0 を返す。左項が null または 0 の場合、右項の評価は行われない。

< <= = == != >= >
     両項を比較し、関係が真ならば、1 を返し、偽の場合は、0 を返す。 == は = と同じ意味である。expr は、まず両項を整数に変換し、数値としての比較を試みる。左右どちらかの項の変換に失敗した場合は、 LC_COLLATE のロケールで指定されている、文字の照合順を使用して、辞書的な比較を行う。

expr の使用例
---------

シェルのメタ文字をクオートする例も含めて、用例をいくつか挙げておく。

Bourne 互換シェルで、シェル変数 foo に 1 を加える。

     foo=$(expr $foo + 1)

変数 $fname に格納されているファイル名から、ディレクトリではない部分を取り出して、表示する。 $fname に / が含まれていなくてもよい。

     expr $fname : '.*/\(.*\)' '|' $fname

次の例で \+ は演算子である (訳注: 細かいことを言うと、grep 流の基本正規表現の演算子。ちなみに、最後の例の + は、expr の文字列演算子である)。

     expr aaa : 'a\+'
     => 3

     expr abc : 'a\(.\)c'
     => b
     expr index abcdef cz
     => 3
     expr index index a
     error--> expr: syntax error
     expr index + index a
     => 0

リダイレクション
********

Unix のシェルは、いくつかの形式のリダイレクション (redirection) --- コマンドの入力元や出力先を変更する手段 --- をたいてい用意している。しかし、ある一つの便利なリダイレクションは、シェルではなく、独立したコマンドによって行われる。この章では、そのコマンドについて説明する。

tee: 出力を複数のファイルやプロセスにリダイレクトする
=============================

tee コマンドは、標準入力を標準出力にコピーするとともに、引数として指定されたファイル (複数可) にもコピーする。これは、あるデータをパイプに送るだけでなく、同時にそのコピーを保存したい場合に、便利である。

書式:

     tee [OPTION]... [FILE]...

書き出し先のファイルがまだ存在していなければ、作成する。書き出し先のファイルがすでに存在している場合は、-a オプションを使用しないかぎり、ファイルに前からあったデータは上書きされる。

GNU coreutils の従来のバージョンでは (v5.3.0 - v8.23)、 FILE として - を指定すると、tee は入力のコピーをもう一つ標準出力に書き出していた。しかし、二重になった出力は、あまり役に立つものではなかったので、現在では POSIX の規格に従い、そこではっきりと規定されているように、 - をそういう名前のファイルとして取り扱うようになっている。

このプログラムでは以下のオプションが使用できる。参照: Common options.

-a
--append
     指定されたファイルの末尾に標準入力を追加する。すなわち、ファイルを上書きしない。

-i
--ignore-interrupts
     割り込みシグナルを無視する。

-p
--output-error[=MODE]
     出力にエラーがあったときの動作を調整する。長い形式のオプションを使えば、下記の MODE から動作を選択することができる。

     warn
          パイプを含めて、出力のオープンや書き出しでエラーが起きると、警告メッセージを出す。エラー発生後もまだオープンされているファイルやパイプがあれば、それに対する書き込みは続行される。出力のいづれかにエラーがあれば、終了ステータスは失敗を示す。

     warn-nopipe
          これが、MODE が指定されないときや、短い形式の -p が使用されたときのデフォルトの MODE である。パイプ以外について、出力のオープンや書き出しでエラーが起きると、警告メッセージを出す。エラー発生後もまだオープンされているファイルやパイプがあれば、それに対する書き込みは続行される。パイプ以外の出力にエラーがあれば、終了ステータスは失敗を示す。

     exit
          パイプを含めて、出力のオープンや書き出しでエラーが起きると、終了する。

     exit-nopipe
          パイプ以外について、出力のオープンや書き出しでエラーが起きると、終了する。

大量のデータの転送を行いながら、同時にそのデータのサマライズも行いたい、改めてデータを読み直すようなことはしたくない。tee は、そういうときに便利である。たとえば、DVD イメージをダウンロードしているとき、その場ですぐ、署名やチェックサムを確認したくなることがよくある。単に次のようにするのは、効率が悪い。

     wget http://example.com/some.iso && sha1sum some.iso

上記コマンドの問題点の一つは、ただでさえ時間のかかる SHA1 の計算に取りかかる前に、ダウンロードが完了するのを待たなければならないことだ。たぶん、さらに問題なのは、上記のやり方では、 DVD イメージを改めて読み直さなければならないことだろう (一度目の読み込みは、ネットワークから)。

こうした作業を行う効率的な方法は、ダウンロードと SHA1 の計算を同時に、交互に実行することである。そうすれば、プロセス全体が平行してスムーズに進むので、無駄な時間を使わずに、チェックサムが手に入る。

     # ちょっと凝った方法。プロセス置換の実例をご覧に入れるため。
     wget -O - http://example.com/dvd.iso \
       | tee >(sha1sum > dvd.sha1) > dvd.iso

こうすれば、tee は、出力を目当てのファイルに書き出すだけでなく、パイプにも書き出す。そして、後者では、sha1sum を実行し、最終的なチェックサムを dvd.sha1 という名前のファイルに保存することになる。

しかし、気をつけていただきたい。上記の例は、プロセス置換 (process substitution) と呼ばれる最近のシェルの機能を当てにしている (上記の>(command) という構文のことである。See Process Substitution (The Bash Reference Manual).)。そのため、zsh, bash, ksh ではうまく動作するが、/bin/sh では動作しない。従って、こうしたコードをシェルスクリプトで使用するときは、スクリプトの先頭に #!/bin/bash などと書くことを忘れてはいけない。

次のことにも気をつけていただきたい。プロセス置換のいづれかが (あるいは、パイプに渡された標準出力が)、データをすべて処理し尽くす前に終了してしまうことがあるかもしれない。そうした場合に、tee が入力の処理を続行して、それを残っている出力先に渡すことができるようにするには、 -p オプションが必要になる。

上記の例は、書き出しを 1 個のファイルと 1 個のプロセスに行っているだけだ。その程度なら、もっと普通の、もっと移植性のある使い方をした方がずっとよい。

     wget -O - http://example.com/dvd.iso \
       | tee dvd.iso | sha1sum > dvd.sha1

tee が二つのプロセスに書き込むように、この例を拡張して、MD5 と SHA1 のチェックサムを平行して計算させることもできる。その場合は、プロセス置換が必要になる。

     wget -O - http://example.com/dvd.iso \
       | tee >(sha1sum > dvd.sha1) \
             >(md5sum > dvd.md5) \
       > dvd.iso

このテクニックは、パイプから入ってくるデータの圧縮したコピーを作りたいときにも、役に立つ。 du -ak の出力するディスク使用量のデータを要約して、グラフィカルに表示するツールを考えていただきたい。ディレクトリ階層が膨大だと、du -ak は実行に長い時間がかかるだろうし、いともたやすくテラバイトのデータを作成してくれるだろう。そこで、du コマンドをむやみに再実行することはやりたくない。また、圧縮されていない出力を保存しておきたくもない。

これを効率の悪い方法でやると、du の出力全部の圧縮を済ませるまで、 GUI ツールを起動することすらできない。

     du -ak | gzip -9 > /tmp/du.gz
     gzip -dc /tmp/du.gz | xdiskusage -a

tee とプロセス置換を使えば、GUI ツールを直ちに起動できるし、圧縮ファイルの展開も全くやらないですむ。

     du -ak | tee >(gzip -9 > /tmp/du.gz) | xdiskusage -a

最後にもう一つ。常に 2 種類以上の圧縮した tar アーカイブ (tarball) を一度に作ることにしている場合は、より効率のよいやり方ができるかもしれない。たとえば、make dist が gzip と bzip2 の両方で圧縮した tar アーカイブを作成するような場合だ。automake が生成する Makefile のルールは、たいてい、こんなふうにコマンドを連続して実行することで、圧縮した tar アーカイブを二つ作成している (少し単純化してある)。

     tardir=your-pkg-M.N
     tar chof - "$tardir" | gzip  -9 -c > your-pkg-M.N.tar.gz
     tar chof - "$tardir" | bzip2 -9 -c > your-pkg-M.N.tar.bz2

しかしながら、アーカイブの作成・圧縮の対象になっているディレクトリ階層が、数メガバイトより大きい場合は --- 使用しているシステムがマルチプロセッサを搭載し、メモリがふんだんにある場合はなおさらそうだが --- ディレクトリの中身を 1 回だけ読み込み、圧縮プログラムを平行して走らせることで、ずっと効率のよい仕事ができる。

     tardir=your-pkg-M.N
     tar chof - "$tardir" \
       | tee >(gzip -9 -c > your-pkg-M.N.tar.gz) \
       | bzip2 -9 -c > your-pkg-M.N.tar.bz2

プロセス置換が表示する出力をさらに処理したいとしよう。もし、そうしたプロセスがアトミックな書き出しをしているならば (すなわち、一度の書き出しが、システムの PIPE_BUF サイズよりも小さければ)、そういうことも次のような構文で可能である。

     tardir=your-pkg-M.N
     tar chof - "$tardir" \
       | tee >(md5sum --tag) > >(sha256sum --tag) \
       | sort | gpg --clearsign > your-pkg-M.N.tar.sig

終了ステータス 0 は成功を示し、0 以外の値は失敗を示す。

ファイル名操作
*******

この章では、ファイル名操作に使うコマンドについて説明する。

basename: ファイル名からディレクトリと接尾辞を取り除く
================================

basename は、NAME の先頭にディレクトリ部分があれば、それを取り除く。

書式:

     basename NAME [SUFFIX]
     basename OPTION... NAME...

SUFFIX が指定されていて、それが NAME の末尾と同一ならば、 SUFFIX の部分も NAME から取り除かれる。気をつけていただきたいが、ファイル名の末尾のスラッシュは、接尾辞のマッチングに先立って除去されるので、 SUFFIX にスラッシュが含まれていると、指定に効果がないことになる。 basename は、結果を標準出力に表示する。

basename と dirname は合わせて設計されており、もし ls "$name"
が成功するならば、cd "$(dirname "$name")"; ls "$(basename "$name")"
というコマンドの連続も成功するようになっている。
これは、ファイル名の末尾に改行が付いている場合を除いて、あらゆる場合にうまく行く。

POSIX によれば、NAME が空の場合や // の場合に、結果がどうなるかは、実装側で決めてよいことになっている。前者の場合、GNU の basename は、空文字列を返す。後者の場合、// と / とが別のものであるプラットフォームでは、結果は // になり、全く区別しないプラットフォームでは、結果は / になる。

このプログラムでは以下のオプションが使用できる。参照: Common options. オプションはオペランドの前に置かなければならない。

-a
--multiple
     複数の引数を受け付ける。すべての引数は NAME として処理される。このオプションを使用する場合、SUFFIX を指定するならば、-s オプションを使わなければならない。

-s SUFFIX
--suffix=SUFFIX
     末尾にある SUFFIX を除去する。このオプションを指定すると -a オプションも指定したことになる。

-z
--zero
     各行の末尾に改行ではなく、ゼロバイト (ASCII NUL) を出力する。このオプションを使用すると、出力するデータの途中に改行が現れる場合でも、他のプログラムがその出力を解析できるようになる。

終了ステータス 0 は成功を示し、0 以外の値は失敗を示す。

用例:

     # "sort" を出力する。
     basename /usr/bin/sort

     # "stdio" を出力する。
     basename include/stdio.h .h

     # "stdio" を出力する。
     basename -s .h include/stdio.h

     # "stdio", "stdlib" の順に出力する。
     basename -a -s .h include/stdio.h include/stdlib.h

dirname: ファイル名から最後の要素を取り除く
==========================

dirname は、各 NAME からスラッシュで区切られた最後の要素を取り除いて、残りのすべてを表示する。その際、最後の要素の左右どちらにあるスラッシュも除去される。 NAME を構成する文字列にスラッシュが一つも含まれない場合、 dirname は (カレントディレクトリを意味する) . を表示する。

書式:

     dirname [OPTION] NAME...

NAME は実在するファイル名でなくても構わないが、実在するファイル名ならば、この操作によって、最後の要素それ自体がディレクトリである場合も含めて、最後の要素が存在するディレクトリが、利用できる形で表示される。

basename と dirname は合わせて設計されており、もし ls "$name"
が成功するならば、cd "$(dirname "$name")"; ls "$(basename "$name")"
というコマンドの連続も成功するようになっている。
これは、ファイル名の末尾に改行が付いている場合を除いて、あらゆる場合にうまく行く。

POSIX によれば、NAME が // の場合に、結果がどうなるかは、実装側で決めてよいことになっている。 GNU の dirname について言うと、// と / とが別のものであるプラットフォームでは、結果は // になり、全く区別しないプラットフォームでは、結果は / になる。

このプログラムでは、以下のオプションが使える。参照: Common options.

-z
--zero
     各行の末尾に改行ではなく、ゼロバイト (ASCII NUL) を出力する。このオプションを使用すると、出力するデータの途中に改行が現れる場合でも、他のプログラムがその出力を解析できるようになる。

終了ステータス 0 は成功を示し、0 以外の値は失敗を示す。

用例:

     # "/usr/bin" を出力する。
     dirname /usr/bin/sort
     dirname /usr/bin//.//

     # "dir1", "dir2" の順に出力する。
     dirname dir1/str dir2/str

     # "." を出力する。
     dirname stdio.h

pathchk: ファイル名の有効性や可搬性を検査する
===========================

pathchk は、ファイル名が有効かどうか、可搬性があるかどうかを検査する。

書式:

     pathchk [OPTION]... NAME...

pathchk は各 NAME に対して、以下の条件のどれかが真ならば、エラーメッセージを出す。

 1. NAME 中の実在するディレクトリの一つが、検索 (実行) 許可を持っていない。

 2. NAME の長さが、オペレーティング・システムによってサポートされている最大長を越えている。

 3. NAME の構成要素の一つの長さが、それが存在することになるファイルシステムによってサポートされている最大長を越えている。

実在しないファイル名を指定しても、エラーにはならない。その名前のファイルが、上記の条件内で作成可能であればよい。

このプログラムでは以下のオプションが使用できる。参照: Common options. オプションはオペランドの前に置かなければならない。

-p
     実際に使用しているファイルシステムに基づいて検査を行うのではなく、以下の条件を調べて、そのどれかが真ならば、エラーメッセージを出す。

      1. ファイル名が空である。

      2. ファイル名に、どのシステムでもファイル名に使用できる文字として POSIX が規定している文字セット以外の文字が含まれている。すなわち、ASCII 英数字、.、_、-、/ 以外の文字が使用されている。

      3. ファイル名の長さや、その構成要素の一つの長さが、 POSIX の規格で可搬性のために最小限サポートしなければならないとされている長さを越えている。

-P
     ファイル名が空だったり、- で始まる構成要素を含んでいたりすると、エラーメッセージを出す。

--portability
     ファイル名が POSIX に準拠しているすべてのホストで使えるものでなければ、エラーメッセージを出す。このオプションは、-p -P と同じことである。

終了ステータス:

     0: 指定されたすべてのファイル名が検査のすべてにパスした場合。
     1: それ以外。

mktemp: テンポラリファイルやディレクトリを作成する
=============================

mktemp は、テンポラリファイルやテンポラリディレクトリの作成を行う。

書式:

     mktemp [OPTION]... [TEMPLATE]

mktemp は、TEMPLATE を基にして、安全なテンポラリファイルやディレクトリを作成し、その名前を表示する。 TEMPLATE を指定する場合、その最後の構成部分に少なくとも 3 個の連続する X が含まれていなければならない。TEMPLATE を省略した場合は、tmp.XXXXXXXXXX というテンプレートが使用され、 --tmpdir オプションが暗黙のうちに指定されることになる。 TEMPLATE 中の X が連続する最後の部分は、英数字で置き換えられる。従って、大文字小文字を区別するファイルシステムなら、テンプレートに連続する N 個の X が含まれていると、作成されるファイル名には、 62 の N 乗とおりの可能性があることになる。

昔のスクリプトでは、テンポラリファイルを作成する際、そのプログラム名にプロセス ID ($$) を拡張子として付けで済ますのが習慣だった。しかし、この命名法は、名前の推測が容易であり、従って、競合状態を起こしやすいという弱点がある。攻撃者としては、テンポラリファイルに使われそうな名前でシンボリックリンクを作っておけばよい。そうすれば、スクリプトが未使用のファイルだと考えて、テンポラリファイルのファイルハンドルを開いたとき、実際にはすでに存在しているファイルの更新をしているということになる。同じ命名法を使ってディレクトリを作成するのは、もう少し安全である。作成しようとするディレクトリがすでに存在していると、mkdir は実行に失敗するからだ。とは言え、こちらもサービス不能化攻撃 (denial of service attacks) を可能にしてしまうわけで、やはり良策とは言えない。それ故、新しいスクリプトでは mktemp コマンドを使用するべきである。そうすれば、生成されるファイル名が確実に予測不可能になるので、実行中のスクリプトがテンポラリファイルの名前を知っているというまさにその事実が、ファイルを作成したのはそのスクリプトであり、他のユーザによってそのファイルが変更されることはありえないと、間違いなく示すことになる。

ファイルを作成する場合、作成されるファイルには現在のユーザに対する読み込みと書き出しの許可が付くが、グループやその他のユーザに対しては、いかなる許可も付かない。現在の umask がより厳格な場合、付けられる許可はさらに厳しくなる。

用例をいくつか挙げてみる (ただし、注意していただきたいが、お手元でこの通り実行しても、おそらくファイル名は違ったものになるはずだ)。

  * カレントディレクトリにテンポラリファイルを作成する。

          $ mktemp file.XXXX
          file.H47c

  * 一般的な拡張子を付けて、テンポラリファイルを作成する。

          $ mktemp --suffix=.txt file-XXXX
          file-H08W.txt
          $ mktemp file-XXXX-XXXX.txt
          file-XXXX-eI9L.txt

  * ユーザが環境変数 TMPDIR で指定しているディレクトリを基点として、その下に安全な FIFO を作成する。TMPDIR が設定されていない場合は、 /tmp ではなく、カレントディレクトリを基点として使用する。肝腎な点は、mktemp は FIFO を作成しないが、FIFO を置くことができる安全なディレクトリなら作成できるということである。ディレクトリや FIFO を作成することができなかったときは、シェルを終了する。

          $ dir=$(mktemp -p "${TMPDIR:-.}" -d dir-XXXX) || exit 1
          $ fifo=$dir/fifo
          $ mkfifo "$fifo" || { rmdir "$dir"; exit 1; }

  * 可能ならば、テンポラリファイルを作成して使用するが、作成に失敗しても、エラーメッセージを出さない。ファイルは、環境変数 TMPDIR が設定されていれば、そこで指名されているディレクトリに作られるが、設定されていなければ、/tmp に作られる。

          $ file=$(mktemp -q) && {
          >   # $file をこのブロックの内側でのみ使用することにすれば、
          >   # 安全である。$file を引用符で囲んでいるのは、$TMPDIR が、
          >   # 従って、$file が、ホワイトスペースを含んでいるかも
          >   # しれないからだ。
          >   echo ... > "$file"
          >   rm "$file"
          > }

  * 擬似ランダム文字発生装置として動作する (カレントディレクトリの内容によって影響を受けるので、完全にランダムではない)。セキュリティホールを避けたいならば、生成された名前を使って、ファイルを作ってはいけない。

          $ mktemp -u XXX
          Gb9
          $ mktemp -u XXX
          nzC

このプログラムでは以下のオプションが使用できる。参照: Common options.

-d
--directory
     ファイルではなく、ディレクトリを作成する。作成されるディレクトリには現在のユーザに対して、読み、書き、検索の許可が付くが、グループやその他のユーザに対しては、いかなる許可も付かない。現在の umask がより厳格な場合、付けられる許可はさらに厳しくなる。

-q
--quiet
     ファイルやディレクトリの作成に失敗しても、エラーメッセージを出さない。終了ステータスは、ファイルが作成されたかどうかをやはり反映する。

-u
--dry-run
     既存のファイルの名前と重ならないテンポラリファイル用の名前を生成するが、ファイルシステムの内容を変更することはない (訳注: 要するに、テンポラリファイル名を生成表示するだけで、実際にファイルを作成することはないということ)。このコマンドの出力を使って、新しいファイルを作るのは、本質的に安全ではない。名前の生成とその使用との間には、時間差があり、その間に他のプロセスが同じ名前でオブジェクトを作成することもありえるからである。

-p DIR
--tmpdir[=DIR]
     TEMPLATE をディレクトリ DIR を基点とする相対パスとして扱う。 DIR が指定されていない場合や (ロングオプションの --tmpdir でのみ可能)、空文字列の場合は、環境変数 TMPDIR が設定されていれば、その値を使用し、設定されていなければ、/tmp を使用する。このオプションを指定する場合、 TEMPLATE は絶対パスであってはならない。とは言え、TEMPLATE にスラッシュが含まれていても構わないが、その場合、途中にあるディレクトリはすでに存在していなければならない。

--suffix=SUFFIX
     TEMPLATE の末尾に SUFFIX を追加する。SUFFIX はスラッシュを含んでいてはならない。--suffix を指定する場合、 TEMPLATE は X で終わっていなければならない。 --suffix が指定されていない場合は、TEMPLATE 中の最後の X の位置を調べることで、SUFFIX としてふさわしいものを推測する。このオプションが存在するのは、デフォルトの TEMPLATE を使用しているとき、 X で始まる SUFFIX を付けられるようにするためである。

-t
     TEMPLATE を、環境変数 TMPDIR が設定されていれば、その値であるディレクトリ直下の 1 個のファイルとして扱う。 TMPDIR が設定されていなければ、-p で指定されるディレクトリ直下、それ以外の場合は、/tmp 直下になる。なお、TEMPLATE にスラッシュが含まれていてはならない。このオプションは非推奨である。 -t なしで -p を使う方が (TMPDIR よりコマンドラインの指定を優先するという点で) デフォルトの動作として優れているし、 (途中のディレクトリも指定できるという点で) 柔軟性も上だからである。

終了ステータス:

     0: ファイルが作成された場合。
     1: それ以外。

realpath: ファイル名を展開して表示する
========================

realpath は、すべてのシンボリックリンクを展開し、 /./ や /../ に対する参照を解決する。さらに、余分な / 文字の削除も行う。デフォルトでは、指定したファイル名のうち、最後の要素以外のすべての要素が実在していなければならない。

書式:

     realpath [OPTION]... FILE...

このプログラムでは以下のオプションが使用できる。参照: Common options.

-e
--canonicalize-existing
     指定されたファイル名中のすべての構成要素が実在することを確認する。存在しなかったり、利用できなかったりする要素があると、-q オプションが指定されていないかぎり、realpath はエラーメッセージを出し、0 以外の終了コードで終了する。ファイル名の末尾にスラッシュを付けると、その名前はディレクトリであるという指定になる。

-m
--canonicalize-missing
     指定されたファイル名中に存在しなかったり、使用できなかったりする構成要素があれば、それをディレクトリとして処理する。

-L
--logical
     指定されたファイル名中にあるシンボリックリンクの展開を行うが、シンボリックリンクに .. という要素が後続している場合は、シンボリックリンクを展開するより前に、そちらを先に処理する。 (訳注: 例を挙げた方が、わかりやすいだろう。symlink-directory/../.. といったファイル名が与えられた場合、symlink-directory というシンボリックリンクそのものの親ディレクトリの親ディレクトリに展開するということ。次項の注と比較していただきたい。)

-P
--physical
     指定されたファイル名中にあるシンボリックリンの展開を行う際、シンボリックリンクに .. という要素が後続している場合も、シンボリックリンクを展開してから、.. の処理を行う。こちらがデフォルトの動作モードである。(訳注: すなわち、 symlink-directory/../.. といったファイル名が与えられた場合、シンボリックリンクの参照先の親ディレクトリの親ディレクトリに展開する。)

-q
--quiet
     指定されたファイル名についてエラーメッセージを出力しない。

--relative-to=FILE
     オプション引数に指定したファイルを基点とする相対パスとして、ファイル名を展開する。このオプションは、ファイルの存在に関して -m や -e オプションを認識することに注意していただきたい。

--relative-base=BASE
     このオプションは --relative-to と一緒に使うこともでき、その場合は、操作対象の FILE が BASE 以下のディレクトリに存在するときにのみ、相対パス名を表示するように、--relative-to の出力に制限を課す。 FILE が BASE 以下のディレクトリに存在しないときは、出力は絶対パスのファイル名になる。--relative-to を指定しなかった場合、 BASE 以下のディレクトリに存在するファイルは、BASE を基点とする相対パスで表示される。--relative-to も指定するなら、そのディレクトリは BASE の下位ディレクトリでなければならず、さもないと、このオプションは効果を持たない。このオプションは、ファイルの存在に関して -m や -e オプションを認識することに注意していただきたい。例を挙げよう。

          realpath --relative-to=/usr /tmp /usr/bin
          => ../tmp
          => bin
          realpath --relative-base=/usr /tmp /usr/bin
          => /tmp
          => bin

-s
--strip
--no-symlinks
     シンボリックリンクの展開を行わない。すなわち、/./ や /../ の参照の解決と、余分な / 文字の削除だけを行う。 -m オプションと組み合わせた場合、realpath は与えられたファイル名に対して操作を行うだけであり、その各要素が存在しているかどうか、実在のファイルに当たってみることはない。

-z
--zero
     各行の末尾に改行ではなく、ゼロバイト (ASCII NUL) を出力する。このオプションを使用すると、出力するデータの途中に改行が現れる場合でも、他のプログラムがその出力を解析できるようになる。

終了ステータス:

     0: すべてのファイル名が問題なく表示できた場合。
     1: それ以外。

作業環境
****

この章では、現在作業中の環境を表示したり、変更したりするコマンドを説明する。ここで環境というのは、カレントディレクトリ、端末の設定などである。次章で取り上げるユーザ関係のコマンドも参照していただきたい。

pwd: 現在作業中のディレクトリを表示する
======================

pwd は、カレントディレクトリの名前を表示する。

書式:

     pwd [OPTION]...

このプログラムでは以下のオプションが使用できる。参照: Common options.

-L
--logical
     環境変数 PWD の値が、. や .. を含まないカレントディレクトリの絶対パス名であっても、シンボリックリンクは含んでいるかもしれない。その場合は、その値をそのまま出力する。それ以外の場合は、デフォルトの -P オプションと同じ処理を行う。

-P
--physical
     カレントディレクトリについて、参照を完全に解決した名前を表示する。すなわち、表示される名前のすべての要素が、本物のディレクトリの名前になり、シンボリックリンクは一つも含まれない。

-L と -P のオプションが両方とも指定されている場合は、最後に指定された方が優先される。どちらのオプションも指定されない場合は、環境変数  POSIXLY_CORRECT が設定されていないかぎり、この実装では、 -P がデフォルトとして使用される。

シェルの組み込み機能の pwd やエイリアスのために、 pwd に何の修飾も付けずに対話的に使ったり、スクリプトの中で使ったりすると、動作がここで述べているものとは違うことがあるかもしれない。シェルによる干渉を避けるためには、env 経由で pwd を起動すればよい (すなわち、env pwd ... のようにだ)。

終了ステータス 0 は成功を示し、0 以外の値は失敗を示す。

stty: 端末の諸特性を表示・変更する
====================

stty は、たとえばボーレート (baud rate) のような、端末の諸特性を表示、または変更する。

書式:

     stty [OPTION] [SETTING]...
     stty [OPTION]

tty ラインの設定 (訳注: 上記書式の SETTING) を一つも指定しない場合、 stty は、ボーレートと (それをサポートしているシステムでは) ライン制御規則番号 (line discipline number)、それに、ライン設定のうち stty sane によって設定される値から変更のあるものを表示する。デフォルトでは、モードの取得や設定は、標準入力に結びついている tty ラインに対して行うが、これは --file オプションによって変更することができる。

stty では、以下で述べるように、オプションではないたくさんの引数が使える。そうした引数は、端末ライン運用の様々な面を変更する。

このプログラムでは以下のオプションが使用できる。参照: Common options.

-a
--all
     現在のすべての設定を人間に読みやすい形で表示する。このオプションを指定したときには、ラインの設定はできない。

-F DEVICE
--file=DEVICE
     標準入力に結びついている tty ラインを操作の対象にする代わりに、 DEVICE で指定されたファイル名を使ってオープンするラインを操作の対象にする。このオプションが必要なのは、POSIX 準拠の tty をオープンするには、 O_NONDELAY フラグを使う必要があるからだ。そうしないと、POSIX 準拠の tty は、clocal フラグがセットされていない場合に、キャリア検出線 (carrier detect line) が活発化するまで、ブロッキングを起こす。そんなわけで、デバイスのオープンは、いつも通りのやり方で (訳注: たとえば、stty < /dev/ttyS1 といった形で) シェルにやらせておけばよい、というわけには必ずしも行かないのである。

-g
--save
     現在の設定を別の stty コマンドを使って再現する際に、その引数として使えるような形で、現在のすべての設定を表示する。このオプションを指定したときには、ラインの設定はできない。

設定の多くは、前に - を付けることで OFF にすることができる。以下では、そうした引数については、説明中に「無効化できる」と記しておいた。説明そのものは、有効にする場合について、すなわち、- で OFF にしない場合について述べている (「無効にした場合」とはっきりことわっている場合は、もちろん別である)。

設定の中には、すべての POSIX 準拠システムで利用できるとはかぎらないものもある。そうしたものは、拡張機能を使用しているからだ。以下では、そうした引数については、説明中に「非 POSIX」と記しておいた。非 POSIX のシステムであっても、そうした設定が使えないことがあるかもしれないが、あらゆる場合について書いておくことは、不可能である。とりあえず、試してみていただきたい。

stty がインストールされるのは、POSIX ターミナルインターフェースを備えたシステムだけである。従って、移植を考慮したスクリプトでは、非 POSIX システムに stty コマンドが存在することを当てにしない方がよい。

終了ステータス 0 は成功を示し、0 以外の値は失敗を示す。

制御関係の設定
-------

制御関係の設定:

parenb
     出力にパリティビットを生成し、入力にもパリティビットがあるものと期待する。無効化できる。

parodd
     パリティを奇数に設定する。無効化できる (この設定の場合、- の前置は偶数パリティを意味する)。

cmspar
     "stick" (mark/space) パリティを使用する。 parodd が設定されている場合、このパリティビットは常に 1 である。 parodd が設定されていない場合、このパリティビットは常に 0 だ。非 POSIX。無効化できる。

cs5
cs6
cs7
cs8
     キャラクタ・サイズを 5, 6, 7, 8 ビットにする。

hup
hupcl
     最後のプロセスが tty をクローズするとき、ハングアップ・シグナルを送る。無効化できる。

cstopb
     1 キャラクタにつき 2 個のストップビットを使用する。無効化できる (この設定の場合、- の前置は 1 個のストップビット使用を意味する)。

cread
     入力の受信を許可する。無効化できる。

clocal
     モデムのコントロール・シグナルを無効にする。無効化できる。

crtscts
     RTS/CTS フロー制御を有効にする。非 POSIX。無効化できる。

cdtrdsr
     DTR/DSR フロー制御を有効にする。非 POSIX。無効化できる。

入力に関する設定
--------

以下の設定は、端末から受け取るデータに対する操作を制御する。

ignbrk
     ブレーク (break) 文字を無視する。無効化できる。

brkint
     ブレークが割り込みシグナルを発生するようにする。無効化できる。

ignpar
     パリティエラーのある文字を無視する。無効化できる。

parmrk
     パリティエラーをマークする (その印として 255, 0 (0xFF, 0x00) という 2 文字の連続を使う)。無効化できる。

inpck
     入力のパリティチェックを有効にする。無効化できる。

istrip
     入力文字の高位ビット (8 番目のビット) をクリアする。無効化できる。

inlcr
     改行文字 (newline) を復帰文字 (carriage return) に変換する。無効化できる。

igncr
     復帰文字を無視する。無効化できる。

icrnl
     復帰文字を改行文字に変換する。無効化できる。

iutf8
     入力文字が UTF-8 で符号化されていると見なす。無効化できる。

ixon
     XON/XOFF フロー制御を有効にする (すなわち、Ctrl-S/Ctrl-Q を有効にする)。無効化できる。

ixoff
tandem
     システムの入力バッファが一杯になりかけたら、stop 文字を送り、バッファがほぼ空に戻ったら、start 文字を送るようにする。無効化できる。

iuclc
     大文字を小文字に変換する。非 POSIX。無効化できる。 ilcuc は実装されていないことに注意していただきたい。そんなものを有効にしたら、ほとんどの (小文字である) Unix のコマンドが、打ち込めなくなってしまうからだ。

ixany
     どんな文字でも出力を再開できるようにする (これを無効にすると、start 文字のみが出力を再開する)。非 POSIX。無効化できる。

imaxbel
     入力バッファが一杯のとき、文字を受け取ると、入力バッファをフラッシュせずに、ビープ音を鳴らすようにする。非 POSIX。無効化できる。

出力に関する設定
--------

以下の設定は、端末に送るデータに対する操作を制御する。

opost
     出力に対して後処理 (postprocess) を行う (訳注: すなわち、以下に列挙するようなことをする)。無効化できる。

olcuc
     小文字を大文字に変換する。非 POSIX。無効化できる。 (ouclc は現在のところ、実装されていないことに注意。)

ocrnl
     復帰文字 (carriage return) を改行文字 (newline) に変換する。非 POSIX。無効化できる。

onlcr
     改行文字を復帰文字 + 改行文字に変換する。非 POSIX。無効化できる。

onocr
     行頭に復帰文字を出力しない。非 POSIX。無効化できる。

onlret
     改行が復帰として動作する。非 POSIX。無効化できる。

ofill
     時間で間合いを計る代りに、充填文字 (埋め草文字) を何字か送ることで、遅延を行う。非 POSIX。無効化できる。(訳注: 遅延というのは、端末側の処理が済むまで、データの送出を遅らせること)。

ofdel
     充填文字として ASCII NUL 文字ではなく、ASCII DEL 文字を使う。非 POSIX。無効化できる。

nl1
nl0
     改行 (newline) 用の遅延方式。非 POSIX。

cr3
cr2
cr1
cr0
     復帰 (carriage return) 用の遅延方式。非 POSIX。

tab3
tab2
tab1
tab0
     水平タブ用の遅延方式。非 POSIX。

bs1
bs0
     バックスペース用の遅延方式。非 POSIX。

vt1
vt0
     垂直タブ用の遅延方式。非 POSIX。

ff1
ff0
     改ページ (form feed) 用の遅延方式。非 POSIX。

ローカル設定
------

isig
     特殊文字 interrupt, quit, suspend を有効にする。無効化できる。

icanon
     特殊文字 erase, kill, werase, rprnt を有効にする。無効化できる。

iexten
     POSIX にない特殊文字を有効にする。無効化できる。

echo
     入力した文字をエコーする。無効化できる。

echoe
crterase
     erase 文字を「バックスペース、スペース、バックスペース」としてエコーする。無効化できる。

echok
     kill 文字に続けて、改行文字をエコーする。無効化できる。

echonl
     他の文字のエコーを行わないない場合でも、改行文字はエコーする。無効化できる。

noflsh
     特殊文字 interrupt や quit の後で、フラッシュを行わない。無効化できる。

xcase
     icanon が設定されているとき、小文字を表す文字の頭に \ を付けることで、大文字の入出力を可能にする。非 POSIX。無効化できる。 (訳注: たとえば、大文字しか使えない端末で、ただの A なら小文字の a を意味し、\A なら大文字の A を意味するようにすること。次節「組み合わせ設定」の lcase と termios(3) の XCASE の説明を参照。)

tostop
     端末に書き込もうとしているバックグラウンドジョブを止める。非 POSIX。無効化できる。

echoprt
prterase
     削除した文字を \ と / で囲んで、逆順にエコーする。非 POSIX。無効化できる。(訳注: プリンタ端末で使用する設定らしい。)

echoctl
ctlecho
     制御文字をそのまま表示するのではなく、ハット記法 (^C) でエコーする。非 POSIX。無効化できる。

echoke
crtkill
     行上の各文字を削除することで、特殊文字 kill のエコーを行う際、 echoctl や echok の設定ではなく、echoprt や echoe の設定が指示するところに従う。非 POSIX。無効化できる。

extproc
     LINEMODE を有効にする。LINEMODE を使用すれば、各文字のエコーを遅延の大きいリンクを通して行わないで済む。 Internet RFC 1116 (ftp://ftp.rfc-editor.org/in-notes/rfc1116.txt) も参照していただきたい。非 POSIX。無効化できる。

flusho
     出力を破棄する。この設定は、現在のところ GNU/Linux システムでは無視されることに注意。非 POSIX。無効にできる。

組み合わせ設定
-------

組み合わせ設定:

evenp
parity
     parenb -parodd cs7 に相当する。無効化できる。無効化した場合、 -parenb cs8 と同じになる。

oddp
     parenb parodd cs7 に相当する。無効化できる。無効化した場合、 -parenb cs8 と同じになる。

nl
     -icrnl -onlcr に相当する。無効化できる。無効化した場合、icrnl -inlcr -igncr onlcr -ocrnl -onlret と同じになる。

ek
     特殊文字 erase と kill をデフォルトの値に戻す。

sane
     以下の設定に相当する。

          cread -ignbrk brkint -inlcr -igncr icrnl
          icanon iexten echo echoe echok -echonl -noflsh
          -ixoff -iutf8 -iuclc -ixany imaxbel -xcase -olcuc -ocrnl
          opost -ofill onlcr -onocr -onlret nl0 cr0 tab0 bs0 vt0 ff0
          isig -tostop -ofdel -echoprt echoctl echoke -extproc

     さらに、すべての特殊文字をそのデフォルトの値に設定する。

cooked
     brkint ignpar istrip icrnl ixon opost isig icanon に相当する。さらに、特殊文字 eof と eol が min 及び time と同じ文字になっていれば、eof と eol をデフォルトの値に設定する。無効化できる。無効化した場合は、raw と同じになる。

raw
     以下の設定に相当する。

          -ignbrk -brkint -ignpar -parmrk -inpck -istrip
          -inlcr -igncr -icrnl -ixon -ixoff -icanon -opost
          -isig -iuclc -ixany -imaxbel -xcase min 1 time 0

     無効化できる。無効化した場合は、cooked と同じになる。

cbreak
     -icanon と同じである。無効化できる。無効化した場合は、icanon と同じになる。

pass8
     -parenb -istrip cs8 に相当する。無効化できる。無効化した場合は、 parenb istrip cs7 と同じになる。

litout
     -parenb -istrip -opost cs8 に相当する。無効化できる。無効化した場合は、parenb istrip opost cs7 と同じになる。

decctlq
     -ixany と同じである。非 POSIX。無効化できる。

tabs
     tab0 と同じである。非 POSIX。無効化できる。無効化した場合は、 tab3 と同じになる。

lcase
LCASE
     xcase iuclc olcuc に相当する。非 POSIX。無効化できる。 (この設定は、大文字しか扱えない端末で使用する。)

crt
     echoe echoctl echoke に相当する。

dec
     echoe echoctl echoke -ixany intr ^C erase ^? kill ^U に相当する。

特殊文字
----

特殊文字のデフォルトの値は、システムによって様々である。特殊文字を設定するには、name value という書式を用いる。この name に何が指定できるかは、以下に列挙するが、value には、文字そのもの、ハット記法 (^C)、整数のいづれかを指定することができる。整数は、0x で始まっていれば 16 進数、0 で始まっていれば 8 進数、それ以外の数字なら 10 進数と見なされる。

GNU の stty では、値に ^- や undef を指定すると、その特殊文字を無効にする。(これは、Ultrix の stty と互換性がない。そこでは、特殊文字を無効にするには u という値が使用されるのだ。GNU の stty は、u という値を特別扱いしない。すなわち、その特殊文字として U を設定するだけである。)

intr
     割り込み (interrupt) シグナルを送る。

quit
     中止 (quit) シグナルを送る。

erase
     直前にタイプした文字を削除する。

kill
     現在行を削除する。

eof
     ファイル終端 (end of file) 文字を送る (入力を終了する)。

eol
     行を終端する。

eol2
     行を終端する別の文字。非 POSIX。

discard
     出力を廃棄するか否かをトグルで切り替える文字。非 POSIX。

swtch
     シェルの別の層 (a different shell layer) に切り換える。非 POSIX。

status
     info シグナルを送る。現在のところ Linux ではサポートされていない。非 POSIX。

start
     停止している出力を再開する。

stop
     出力を停止する。

susp
     端末からの停止シグナル (terminal stop signal, SIGTSTP) を送る。

dsusp
     入力をフラッシュしてから、端末からの停止シグナルを送る。非 POSIX。

rprnt
     現在行を表示し直す。非 POSIX。

werase
     直前にタイプした単語 (word) を削除する。非 POSIX。

lnext
     次にタイプする文字が特殊文字であっても、タイプしたとおりの文字として入力する。非 POSIX。(訳注: たとえば、lnext が ^V の場合、^V^D と続けてタイプすると、^D を入力終了の印としてではなく、^D という文字そのものとして入力できるということ。)

特殊設定
----

min N
     -icanon が設定されている際、time の値として指定されている時間が経過するまでの間に、 1 回分の読み込みの条件を満たす最少限の文字数を設定する。

time N
     -icanon が設定されている際、最小限の文字数が読み込まれなかった場合に、読み込みが時間切れになるまでの時間を 10 分の 1 秒単位で設定する。

ispeed N
     入力速度を N に設定する。

ospeed N
     出力速度を N に設定する。

rows N
     端末の行数は N 行だと、tty カーネルドライバに伝える。非 POSIX。

cols N
columns N
     端末の横幅は N 桁だと、カーネルに伝える。非 POSIX。

drain
     保留になっている出力が送出されるのを待ち、その後で設定を適用する。 GNU の stty では、デフォルトで有効になっている。システムが、シリアルな伝送ができない状態になっているかもしれない場合には、このオプションを無効にするとよい。たとえば、ixon (ソフトウェアによるフロー制御) が有効になっている場合に、システムが DC3 文字を受け取っていたりすると (訳注: DC3 は device control 3、すなわち ASCII 0x13、^S)、 -drain の指定なしでは、stty はブロッキングを起こすだろう。無効化できる。非 POSIX。

size
     端末の行数と桁数を表示する。これは、端末が持っていると、カーネルが考えている行数と桁数である。 (カーネルで行数や桁数をサポートしていないシステムでは、通常その代わりに、環境変数 LINES や COLUMNS が使用される。それに対して、GNU の stty は、そうした環境変数について何も知らない。) 非 POSIX。

line N
     ライン制御規則 (line discipline) N を使用する。非 POSIX。

speed
     端末速度を表示する。

N
     入出力の速度を N に設定する。N には次の一つが使える。0 50 75 110 134 134.5 150 200 300 600 1200 1800 2400 4800 9600 19200 38400 exta extb。exta は 19200 と同じであり、extb は 38400 と同じである。GNU/Linux を含む多くのシステムが、もっと早い速度をサポートしている。 stty は、システムがサポートしているならという条件で、次の速度もサポートしている。 57600 115200 230400 460800 500000 576000 921600 1000000 1152000 1500000 2000000 2500000 3000000 3500000 4000000。なお、0 は、-clocal が設定されている場合に、ラインを切断する。

printenv: 環境変数のすべて、あるいは一部を表示する
==============================

printenv は、環境変数の値を表示する。

書式:

     printenv [OPTION] [VARIABLE]...

VARIABLE が一つも指定されていない場合、printenv はすべての環境変数の値を表示する。VARIABLE が指定されている場合は、その変数それぞれについて、設定されていれば値を表示し、設定されていなければ何も表示しない。

このプログラムでは、以下のオプションが使える。参照: Common options.

-0
--null
     各行の末尾に改行ではなく、ゼロバイト (ASCII NUL) を出力する。このオプションを使用すると、出力するデータの途中に改行が現れる場合でも、他のプログラムがその出力を解析できるようになる。

終了ステータス:

     0: 指定されているすべての変数が見つかった。
     1: 指定されている変数のうちに、見つからなかったものがある。
     2: 書き込みエラーが生じた。

tty: 標準入力に接続している端末のファイル名を表示する
=============================

tty は、自分の標準入力に接続している端末のファイル名を表示する。標準入力が端末ではない場合は、not a tty というメッセージを出す。

書式:

     tty [OPTION]...

このプログラムでは、以下のオプションが使える。参照: Common options.

-s
--silent
--quiet
     何も表示しない。終了ステータスを返すだけ。

終了ステータス:

     0: 標準入力が端末である。
     1: 標準入力が端末ではない。
     2: 指定した引数が正しくない。
     3: 書き込みエラーが生じた。

ユーザ情報
*****

この章では、ユーザ関係の情報を表示するコマンドの説明をする。誰がログインしているか、どんなグループに所属しているか、などである。

id: ユーザの ID を表示する
=================

id は、指定されたユーザについて情報を表示する。ユーザが指定されていない場合は、id を実行しているプロセスについて情報を表示する。

書式:

     id [OPTION]... [USER]

USER にはユーザ ID (番号) とユーザ名のどちらも使えるが、ID が頭に + を付けて指定されていないかぎり、まずユーザ名として検索が行われる。 See Disambiguating names and IDs.

デフォルトで表示するのは、実ユーザ ID、実グループ ID、実効ユーザ ID (実ユーザ ID と違う場合)、実効グループ ID (実グループID と違う場合)、それに、補助 (supplemental) グループ ID である。さらに、SELinux が有効になっていて、環境変数 POSIXLY_CORRECT が設定されていない場合は、context=C も表示する。この C はセキュリティ・コンテキストである。

表示される各数値には、それが何であるかを示す文字列が前に付き、対応するユーザ名やグループ名がカッコで囲まれて後ろに続く。

オプションを指定すると、id は上で述べた情報のうち、一部のみを表示する。参照: Common options.

-g
--group
     グループ ID のみ表示する。

-G
--groups
     グループ ID と補助グループ ID のみ表示する。

-n
--name
     ID 番号の代りに、ユーザ名やグループ名を表示する。-u, -g, -G の一つを指定する必要がある。

-r
--real
     実効ユーザや実効グループの ID ではなく、実ユーザや実グループの ID を表示する。 -u, -g, -G のどれか一つを指定する必要がある。

-u
--user
     ユーザ ID のみ表示する。

-Z
--context
     現プロセスのセキュリティ・コンテキストのみを表示する。たいていの場合、それは、親プロセスから継承したユーザのセキュリティ・コンテキストである。 SELinux と SMACK のどちらも有効になっていない場合は、警告メッセージを出し、終了ステータスを 1 にする。

-z
--zero
     出力する項目を NUL 文字で区切る。このオプションは、デフォルトのフォーマットを使用しているときは、使うことができない。

     用例:

          $ id -Gn --zero
          users <NUL> devs <NUL>

プロセスの基本 (primary) グループや 補助 (supplementary) グループは、
通常その親プロセスから継承され、ログイン後ずっと変わらないのが普通だ。
従って、ログイン後にグループ・データベースを変更しても、
現在のログインセッションが続いている間は、id コマンドはその変更を反映しない。
しかし、引数にユーザの名前を指定して id を実行した場合は、
ユーザ・データベースやグループ・データベースの参照が改めて行われるので、
変更した結果が表示されることになる。

終了ステータス 0 は成功を示し、0 以外の値は失敗を示す。

logname: 現在のログイン名を表示する
======================

logname は、自分を呼び出しているユーザの名前を、システムが管理しているファイル (たいていは /var/run/utmp か /etc/utmp) で調べて表示し、ステータス 0 で終了する。自分を呼び出しているプロセスのエントリが存在しない場合は、エラーメッセージを出し、ステータス 1 で終了する。

オプションは、--help と --version だけである。 See Common options.

終了ステータス 0 は成功を示し、0 以外の値は失敗を示す。

whoami: 実効ユーザ ID を表示する
======================

whoami は、現在の実効ユーザ ID に対応するユーザ名を表示する。 id -un コマンドと同じことである。

オプションは、--help と --version だけである。 See Common options.

終了ステータス 0 は成功を示し、0 以外の値は失敗を示す。

groups: ユーザが所属しているグループ名を表示する
============================

groups は、USERNAME が指定されていれば、指定された各ユーザの基本 (primary) グループ名と補助 (supplementary) グループ名を表示し、ユーザ名が指定されていなければ、現在のプロセスの基本グループ名と補助グループ名を表示する。複数の名前が指定されている場合は、各ユーザの名前がグループのリストの前に置かれ、両者の間はコロンで区切られる。

書式:

     groups [USERNAME]...

グループのリストは、id -Gn コマンドの出力と同じである。

オプションは、--help と --version だけである。 See Common options.

プロセスの基本 (primary) グループや 補助 (supplementary) グループは、
通常その親プロセスから継承され、ログイン後ずっと変わらないのが普通だ。
従って、ログイン後にグループ・データベースを変更しても、
現在のログインセッションが続いている間は、groups コマンドはその変更を反映しない。
しかし、ユーザのリストを指定して groups を実行した場合は、
ユーザ・データベースやグループ・データベースの参照が改めて行われるので、
変更した結果が表示されることになる。

終了ステータス 0 は成功を示し、0 以外の値は失敗を示す。

users: 現在ログインしている全ユーザのログイン名を表示する
================================

users は、目下使用しているホストに現在ログインしている全ユーザのユーザ名のリストを、空白で区切って 1 行に表示する。ユーザ名はログインセッションごとに表示されるので、あるユーザが複数のログインセッションを行っていれば、そのユーザの名前はログインセッションの数だけ出力に現れることになる。

書式:

     users [FILE]

引数 FILE の指定がない場合、users はシステムが管理するファイル (たいていは /var/run/utmp か /etc/utmp) からログインしているユーザの情報を引き出す。引数 FILE が指定されている場合は、代りにそのファイルを使用する。/var/log/wtmp が使われることが多い。

オプションは、--help と --version だけである。 See Common options.

users コマンドがインストールされるのは、POSIX 準拠の <utmpx.h> インクルードファイル、またはそれに相当するものが存在するプラットフォームだけである。従って、移植を考慮したスクリプトでは、非 POSIX のプラットフォームにも users コマンドが存在することを当てにしない方がよい。

終了ステータス 0 は成功を示し、0 以外の値は失敗を示す。

who: 現在誰がログインしているかを表示する
=======================

who は、現在ログインしているユーザについての情報を表示する。

書式:

     who [OPTION] [FILE] [am i]

オプション以外の引数が一つもない場合、who は現在ログインしている各ユーザについて、次の情報を表示する。ログイン名、端末ライン、ログイン日時、それにリモート・ホスト名か X ディスプレー名。

オプション以外の引数を一つだけ指定すると、who はそれを、ログインしたユーザを記録しているファイルの名前として、システムが管理しているデフォルトのファイル (たいていは /var/run/utmp か /etc/utmp) の代りに使用する。who に引数として /var/log/wtmp を渡して、これまでに誰がログインしたかを調べるのはよくあることである。

オプション以外の引数を二つ指定すると、whoは、自分を実行しているユーザの情報のみを (自分が接続している標準入力からユーザの見当を付けて)、ホスト名を前に付けて表示する。渡される二つの引数は、全体として who am i になるように、am i とするのが慣例である。

タイムスタンプは、タイムゾーンのルールに従って表示されるが、そのルールを指定しているのは、環境変数 TZ である。 TZ が設定されていない場合は、システムのデフォルトのルールに従って表示される。 See Specifying the Time Zone with TZ (The GNU C Library Reference Manual).

このプログラムでは以下のオプションが使用できる。参照: Common options.

-a
--all
     -b -d --login -p -r -t -T -u と同じである。

-b
--boot
     システムをブートした直近の日時を表示する。

-d
--dead
     終了したプロセスに関する情報を表示する。

-H
--heading
     最初の行に各列の見出しを表示する。

-l
--login
     現在システムがログインの窓口としてユーザを待ち受けているプロセスに関する情報のみを表示する。ユーザ名は常に LOGIN である。

--lookup
     utmp で見つかったホスト名について DNS を検索して正規名を得ようとする。これがデフォルトになっていないのは、インターネットに自動ダイアルアップで接続しているシステムでは、深刻な遅滞を招きかねないからである。

-m
     who am i と同じである。

-p
--process
     init によって生み出されたプロセスのうち、現在活動中のものをリストする。

-q
--count
     ログインしているユーザのログイン名と人数のみを表示する。他のすべてのオプションを無効にする。

-r
--runlevel
     init プロセスの現在のランレベルを表示する (たぶん、直前のランレベルも)。

-s
     無視する。他の版の who との互換性のためにある。

-t
--time
     システムクロックを最後に変更した日時を表示する。

-u
     ログイン日時の後ろに、ユーザが何時間何分端末を使用していないかを (idle 状態かを) 表示する。 . は、ユーザがここ 1 分以内に端末操作をしたことを意味する。 old は、ユーザが 24 時間以上端末を使用していないということである。

-w
-T
--mesg
--message
--writable
     ログイン名の後ろに、ユーザのメッセージ受け入れ状態を示す 1 文字を表示する。

          + write によるメッセージを受け入れる。
          - write によるメッセージを拒否する。
          ? 端末デバイスが見つからない。

who コマンドがインストールされるのは、POSIX 準拠の <utmpx.h> インクルードファイル、またはそれに相当するものが存在するプラットフォームだけである。従って、移植を考慮したスクリプトでは、非 POSIX のプラットフォームにも who コマンドが存在することを当てにしない方がよい。

終了ステータス 0 は成功を示し、0 以外の値は失敗を示す。

システム関連
******

この章では、システム全体に関わる情報を表示したり、変更したりするコマンドを説明する。

date: システムの日付や時刻を表示、設定する
========================

書式:

     date [OPTION]... [+FORMAT]
     date [-u|--utc|--universal]
     [ MMDDhhmm[[CC]YY][.ss] ]

date を FORMAT 引数なしで起動すると、デフォルトの書式を指定して起動するのと同じことになる。デフォルトの書式は、LC_TIME ロケール・カテゴリによって様々である。デフォルトの C ロケールの場合、その書式は '+%a %b %e %H:%M:%S %Z %Y' なので、出力は Thu Mar  3 13:47:51 PST 2005 のような形になる。

通常 date は、環境変数 TZ が指示しているタイムゾーンのルールを使用し、 TZ が設定されていないときは、システムのデフォルトのルールを使用する。 See Specifying the Time Zone with TZ (The GNU C Library Reference Manual).

+ で始まる引数を指定すると、date は現在の日付と時刻を (あるいは、後述する --date オプションで指定した日付と時刻を)、その引数によって定義された書式で表示する。書式を指定するこの引数は、strftime 関数のそれとほぼ同じである。なお、% で始まる変換指定子を除いて、書式文字列中の文字は、変更されずにそのまま表示される。変換指定子については、次節以降で説明する。

終了ステータス 0 は成功を示し、0 以外の値は失敗を示す。

時刻関係の変換指定子
----------

date の時刻関係の変換指定子

%H
     時 (00...23)

%I
     時 (01...12)

%k
     時。一桁のときは、0 ではなく、空白で埋める ( 0...23)。 %_H と同じ。これは GNU の拡張である。

%l
     時。一桁のときは、0 ではなく、空白で埋める ( 1...12)。 %_I と同じ。これは GNU の拡張である。

%M
     分 (00...59)

%N
     ナノ秒 (000000000...999999999)。これは GNU の拡張である。

%p
     現在のロケールで AM や PM に相当するもの。空白になるロケールも多い。正午は PM として、真夜中は AM として扱う。

%P
     %p と同様だが、小文字を使う。これは GNU の拡張である。

%r
     現在のロケールによる 12 時間表記の時刻 (例: 11:11:04 PM)

%R
     24 時間表記の時と分。%H:%M と同じ。

%s
     ジ・エポック (the epoch、Unix 紀元)、すなわち 1970-01-01 00:00:00 UTC からの経過秒数。閏秒のサポートを利用できない場合、閏秒は計算に入れない。用例については、「date の用例」を見ること。 See %s-examples. これは GNU の拡張である。

%S
     秒 (00...60)。閏秒がサポートされている場合、60 になることがある。

%T
     24 時間表記の時、分、秒。%H:%M:%S と同じ。

%X
     現在のロケールによる時刻表示 (例: 23:13:48)

%z
     RFC 2822/ISO 8601 形式の数値によるタイムゾーン (たとえば、-0600 や +0530)。タイムゾーンが特定できない場合は、空になる。この値は、環境変数 TZ によって指定されたタイムゾーンのルールを使用することで、現在の日時に対応した、数値によるタイムゾーンを正しく反映する (訳注: 要するに、夏時間、冬時間が存在する地帯では、それを反映するということ)。操作の対象となる日時は (もしそうしたければ、その日時におけるタイムゾーンのルールも)、 --date オプションによって変更することができる。

%:z
     RFC 3339/ISO 8601 形式の、: を使用する数値によるタイムゾーン (たとえば、-06:00 や +05:30)。タイムゾーンが特定できない場合は、空になる。これは GNU による拡張である。

%::z
     : を使用する数値によるタイムゾーンで、もっとも近い秒まで表示する (たとえば、-06:00:00 や +05:30:00)。タイムゾーンが特定できない場合は、空になる。これは GNU による拡張である。

%:::z
     : を使用する数値によるタイムゾーンで、時間の精度を必要最小限で済ます (たとえば、-06, +05:30, -04:56:02)。タイムゾーンが特定できない場合は、空になる。これは GNU による拡張である。

%Z
     アルファベットによるタイムゾーンの略称 (たとえば、EDT)。タイムゾーンが特定できない場合は、空になる。タイムゾーンがどのようにして特定されるか (訳注: たとえば、アメリカ東部なら、EST (冬時間) と EDT (夏時間) のどちらが選ばれるか) については、%z を参照すること。

日付関係の変換指定子
----------

date の日付関係の変換指定子。

%a
     現在のロケールによる曜日の省略形 (例: Sun)

%A
     現在のロケールによる曜日の省略しない表現。長さは不定 (例: Sunday)

%b
     現在のロケールによる月名の省略形 (例: Jan)

%B
     現在のロケールによる月名の省略しない表現。長さは不定 (例: January)

%c
     現在のロケールによる日付と時刻 (例: Thu Mar  3 23:05:25 2005)

%C
     世紀。%Y に似ているが、下二桁を省略している。たとえば、%Y が 2000 ならば、%C は 20、%Y が -001 ならば、%C は -0 である。通例、少なくとも 2 個の文字からなるが、2 個以上のこともありえる。

%d
     その月の何日目か (例: 01)

%D
     日付。%m/%d/%y と同じ

%e
     その月の何日目か。一桁のときは、0 ではなく、空白で埋める。%_d と同じ。

%F
     ISO 8601 形式の完全な日付。%Y-%m-%d と同じ。日付の形式にこれを選ぶのは、好判断である。標準的な形式だし、年度が 0000...9999 の範囲にある通常の場合に、ソートしやすい。

%g
     ISO 週番号に対応する年度表示だが、世紀の部分を省略している (その結果、00 から 99 の範囲になる)。これは普通 %y と同じ形式、同じ値になるが、ISO 週番号 (%V 参照) が前年、または翌年に属する場合は、そちらの年度が代りに使用される点が異なる。

%G
     ISO 週番号に対応する年度表示。これは普通 %Y と同じ形式、同じ値になるが、 ISO 週番号 (%V 参照) が前年、または翌年に属する場合は、そちらの年度が代りに使用される点が異なる。通常、これが役に立つのは、 %V も一緒に使用するときだけである。たとえば、%G-%m-%d という書式は、ISO 週番号による年度と普段使用する月や日を組み合わせているので、たぶん指定の仕方を間違えている。

%h
     %b と同じ。

%j
     その年の何日目か (001...366)

%m
     月 (01...12)

%q
     四半期 (1...4)

%u
     その週の何日目か (1...7)。1 は月曜日に当たる。

%U
     日曜日を週の最初の日とする、その年の週番号 (00...53)。新しい年の最初の日曜日より前の日々は、第 0 週に属する。

%V
     ISO 週番号。すなわち、月曜日を週の最初の日とする、その年の週番号 (01...53)。1 月 1 日を含む週が、新しい年の日々を 4 日以上含む場合は、その週が第 1 週であると見なされる。そうでない場合は、その週は前年の第 53 週であり、翌週が第 1 週になる。 (ISO 8601 の規格を参照。)

%w
     その週の何日目か (0...6)。0 は日曜日に当たる。

%W
     月曜日を週の最初の日とする、その年の週番号 (00...53)。最初の月曜日より前の新しい年の日々は、第 0 週に属する。

%x
     現在のロケールによる日付の表示 (例: 12/31/99)

%y
     年度の下二桁 (00...99)

%Y
     年度。通例、少なくとも 4 文字だが、もっと多いこともある。0000 年は 0001 の前年であり、-001 年は 0000 の前年である。

文字変換指定子
-------

日付や時刻以外の date の変換指定子。

%%
     1 個の % という文字

%n
     改行

%t
     水平タブ

空き埋めなどのフラグ
----------

特に指定がないかぎり、date は通常、数値の入るフィールドの空きを 0 で埋める。従って、たとえば、数値による月名は常に二桁の数字として出力される。しかし、ジ・エポック (Unix 紀元) 以来の経過秒数では、空きを埋めることはしない。この秒数には決まった長さがないからである。

GNU の拡張として、以下に挙げるフラグの一つを % の後ろに置くことができる (指定するしないは自由)。

-
     (ハイフン) フィールドの空き埋めをしない。出力が人間に見せるためのものである場合に、役に立つ。

_
     (アンダースコア、下線) 空白で空き埋めをする。出力を一定の文字数にする必要があるが、0 で埋めたのでは見にくいという場合に、役に立つ。

0
     (ゼロ) 変換指定子が普通なら空白で埋める場合にも、ゼロで空き埋めをする。

^
     可能なら、大文字を使う。

#
     可能なら、反対の文字を使う。通常大文字のフィールドは小文字になり、小文字のフィールドは大文字になる。

空き埋めの例をいくつか挙げておく。

     date +%d/%m -d "Feb 1"
     => 01/02
     date +%-d/%-m -d "Feb 1"
     => 1/2
     date +%_d/%_m -d "Feb 1"
     =>  1/ 2

これも GNU の拡張だが、フィールドの幅を 10 進数で指定することができる (数字は、上記のフラグがあれば、その後ろに置く)。そのフィールドの出力の加工前の長さが、幅として指定した文字数より短い場合は、右詰めにして、指定サイズにまで空き埋めした結果が書き出される。たとえば、%9B は、右詰めにした月の名前を 9 文字分のフィールドに表示する。

上記のフラグやフィールド幅の指定の後ろに、修飾子 (modifier) を付けることもできる (指定するしないは自由)。修飾子には、次のものがある。

E
     現在のロケールが持つもう一つの日時表記を使用する。この修飾子は、%c, %C, %x, %X, %y, %Y に対して使用できる。たとえば、日本語ロケールで %Ex とすれば、元号による日付を表示するだろう。

O
     現在のロケールが持つもう一つの数字表記を使用する。この修飾子は、数値を表す変換指定子にしか使用できない。

書式が修飾子をサポートしていても、もう一つの表記が利用できない場合、修飾子は無視される。

システムクロックの設定
-----------

+ で始まらない引数を指定すると、date は、(以下で述べるように) その引数で指定した日時にシステムクロックを設定する。システムクロックを設定するには、しかるべき権限が必要である。リブート後も変更を維持するには、システムクロックに合わせてハードウェアクロックも更新する必要があるかもしれないことに注意していただきたい。ご使用のシステムでは、ハードウェアクロックの更新は、自動的に行われないかもしれないからだ。

引き数の構成要素は、すべて数字でなければならない。それは以下の意味を持っている。

(訳注: 念のため、この章の冒頭にあるシステムクロック設定用の書式を再掲しておく。 date [-u|--utc|--universal] [ MMDDhhmm[[CC]YY][.ss] ])

MM
     何月

DD
     (何月の) 何日

hh
     何時

mm
     何分

CC
     年度の上二桁 (省略可)

YY
     年度の下二桁 (省略可)

ss
     何秒 (省略可)

注意していただきたいが、--date や --set オプションは、ここで述べている書式の引数と組み合わせて使うことができない。 --universal オプションは、ここで述べている書式の引数と一緒に使うことができるが、その場合は、指定されている日時が現在地のタイムゾーンではなく、協定世界時 (UTC) に準じているのを示すことになる。

date のオプション
-----------

このプログラムでは以下のオプションが使用できる。参照: Common options.

-d DATESTR
--date=DATESTR
     現在の日時の代りに、日付文字列 DATESTR で指定した日時を表示する。 DATESTR には、よく使われる書式なら、ほとんどどんな書式でも使うことができる。月の名前、タイムゾーン、am や pm、yesterday といった単語、などを含んでいてもよい。たとえば、--date="2004-02-27 14:19:13.489392193 +0530" は、UTC よりも東 5 時間 30 分のタイムゾーンで 2004 年 2 月 27 日 午後 2 時 19 分 13 秒から 489,392,193 ナノ秒経過した瞬間を指定している。

     注意: 現在のところ、入力は、ロケールに依存しない書式でなければならない。たとえば、以下の例の LC_TIME=C は、多くのロケールで正しい日時を再表示させるために必要である。

          date -d "$(LC_TIME=C date)"

     参照: see Date input formats.

--debug
     解析した日時について説明し、現在のタイムゾーンを表示し、間違えた使い方をしている疑いがあれば、警告を出す。

-f DATEFILE
--file=DATEFILE
     ファイル DATEFILE の各行を -d の場合と同じように解析して、生成された日付と時刻を表示する。 DATEFILE が - ならば、標準入力を使用する。処理する日付がたくさんある場合に、このオプションは重宝である。何故ならば、date コマンドを何度も起動するときのシステムのオーバーヘッドは、馬鹿にならないことがあるからだ。

-I[TIMESPEC]
--iso-8601[=TIMESPEC]
     ISO 8601 の書式、%Y-%m-%d を使って、日付を表示する。

     引数 TIMESPEC では、日付の後ろに時刻をどの単位まで追加するかを指定する。以下の一つを指定することができる。

     date
          日付のみを表示する。TIMESPEC を省略した場合のデフォルト。

     hours
          日付にその日の何時かを追加する。

     minutes
          何時何分まで追加する。

     seconds
          何時何分何秒まで追加する。

     ns
          何時何分何秒何ナノ秒まで追加する。

     時刻の部分まで表示するときは、%:z の書式でタイムゾーンも付ける。
     この書式は、使用しているロケールが何であるかを問わず、--date (-d)
     や --file (-f) オプションに対する入力として、常に適切である。

-r FILE
--reference=FILE
     現在の日付と時刻の代りに、FILE の内容を最後に更新した (the last modification) 日付と時刻を表示する。

-R
--rfc-822
--rfc-2822
     日付と時刻を %a, %d %b %Y %H:%M:%S %z という書式を使用し、 C ロケールで評価して表示する。従って、月や曜日の省略形は常に英語になる。一例を挙げると、こんな表示である。

          Fri, 09 Sep 2005 13:51:39 -0700

     この書式は、Internet RFC 2822 (ftp://ftp.rfc-editor.org/in-notes/rfc2822.txt) と RFC 822 (ftp://ftp.rfc-editor.org/in-notes/rfc822.txt) に従っている。インターネットの E メールに関する現在と以前の規格である。

--rfc-3339=TIMESPEC
     Internet RFC 3339 (ftp://ftp.rfc-editor.org/in-notes/rfc3339.txt) が規定している書式を使用して、日付を表示する。この書式は、ISO 8601 の書式のサブセットだが、日付と時刻を区切るのに、T という文字ではなく、空白を使うことをアプリケーションに許しているという相違点がある。この書式は、使用しているロケールが何であるかを問わず、--date (-d)
     や --file (-f) オプションに対する入力として、常に適切である。

     引数 TIMESPEC では、時刻をどこまで表示するかを指定する。以下の一つを指定することができる。

     date
          年から始まる日付だけを表示する。たとえば、2005-09-14。これは、%Y-%m-%d という書式と等価である。

     seconds
          年から始まる日付と秒までの時刻を表示し、両者の間は空白で区切る。一例を挙げると、2005-09-14 00:56:06+05:30。出力の末尾には、協定世界時からの時差が付く。例の場合、+05:30 は、地方時が UTC より 5 時間 30 分進んでいることを意味している。これは、%Y-%m-%d %H:%M:%S%:z という書式と等価である。

     ns
          seconds と似ているが、ナノ秒まで表示する。一例を挙げると、2005-09-14 00:56:06.998458565+05:30。これは、%Y-%m-%d %H:%M:%S.%N%:z という書式と等価である。

-s DATESTR
--set=DATESTR
     日付と時刻を DATESTR に設定する。上記の -d を参照。前節「システムクロックの設定」 も参照すること。Setting the time.

-u
--utc
--universal
     環境変数 TZ が、文字列 UTC0 に設定されているかのように、処理に協定世界時 (UTC, Coordinated Universal Time) を使用する。協定世界時は、歴史的な理由から「グリニッジ標準時 (GMT)」と呼ばれることもよくある。一般にシステムは閏秒を無視するので、日時は正真の UTC ではなく、UTC の近似値になる。

date の使用例
---------

用例をいくつか挙げてみる。前節の -d オプションの説明も参照していただきたい。

  * 一昨日の日付を表示する。

          date --date='2 days ago'

  * 今から 3 ヶ月と 1 日後の日付けを表示する。

          date --date='3 months 1 day'

  * 今年のクリスマスは年の初めから何日目かを表示する。

          date --date='25 Dec' +%j

  * 今日が何月何日かを、省略しない月の名前で表示する。

          date '+%B %d'

     しかし、月の最初の 9 日間では、%d は空きを 0 で埋めた 2 桁のフィールドに展開されるので、この結果はご希望のものとは違うかもしれない。たとえば、date -d 1may '+%B %d' の出力は、May 01 になるのだ。

  * 月のうちの 1 桁の日々に対して、先頭に 0 を付けずに日付を表示したいのなら、 (GNU の拡張である) - フラグを使用すれば、空き埋めを全くしないようにすることができる。

          date -d 1may '+%B %-d'

  * 現在の日付と時刻を、non-GNU 版の date の多くでシステムクロックを設定するときに要求される書式で表示する。

          date +%m%d%H%M%Y.%S

  * システムクロックを 2 分進める。

          date --set='+2 minutes'

  * 日付を RFC 2822 の書式で表示するためには、date --rfc-2822 を使用する。ここに示すのは、出力の一例である。

          Fri, 09 Sep 2005 13:51:39 -0700

  * 日付を表す文字列をジ・エポック (the epoch、Unix 紀元、すなわち、 1970-01-01 00:00:00 UTC) からの経過秒数に変換するには、--date オプションを %s 書式と組み合わせて使用する。これは、データを日付によってソートしたり、グラフ化したり、比較したりする際に、便利である。次のコマンドは、ジ・エポックから 2 分経ったときの、ジ・エポックからの経過秒数を出力する。

          date --date='1970-01-01 00:02:00 +0000' +%s
          120

     日付を表す文字列でタイムゾーン情報を指定しない場合、date は、コンピュータが認識しているタイムゾーンを使用して、その文字列を解釈する。たとえば、使用しているコンピュータのタイムゾーンが、マサチューセッツ州のケンブリッジのものならば、それは UTC より 5 時間遅れているので、次のようになる。

          # 現在地のタイムゾーンを使用
          date --date='1970-01-01 00:02:00' +%s
          18120

  * 日付の付いたデータをソートしたり、グラフ化したりしているとしよう。その日付の加工前の値は、ジ・エポックからの経過秒数で表されているかもしれない。だが、946684800 といった日付を見て、「ああ、イギリスのグリニッジの 2000 年の最初の 0 秒だね」と、さりげなく言える人は、めったにいない。

          date --date='2000-01-01 UTC' +%s
          946684800

     なお、上と同じ結果は、--utc (-u) オプションを使っても得られ、その場合は、日付を表す文字列で UTC を省略することができる。とは言え、--utc を使う方法は、%s を始め、多くの書式文字列では、日付文字列で UTC を使うのと同じ結果をもたらすものの、協定世界時からの時差が 0 ではないタイムゾーンでは、 %z のようなタイムゾーンによって値が変わってくる書式文字列に対しては、異なる結果をもたらすことになるだろう。

          date -u --date=2000-01-01 +%s
          946684800

     こうした秒数という扱いにくいデータをもっと読みやすい形に変換し直すには、次のようなコマンドを使う。

          # 現在地のタイムゾーンを使用
          date -d '1970-01-01 UTC 946684800 seconds' +"%Y-%m-%d %T %z"
          1999-12-31 19:00:00 -0500

     coreutils 5.3.0 以来使用できるようになった @ という表記に頼っても構わないなら、上記のコマンドを短くすることができる (参照: Seconds since the Epoch)。

          date -d @946684800 +"%F %T %z"
          1999-12-31 19:00:00 -0500

     UTC の日付や時刻を出力した方がよいことも多い。

          date -u -d '1970-01-01 946684800 seconds' +"%Y-%m-%d %T %z"
          2000-01-01 00:00:00 +0000

  * 閏秒は秒数計算に入れないのが一般的だが、例外的なシステムもある。閏秒は予測できないものなので、閏秒を計算に入れる例外的なシステムでは、秒数による計算と未来の日時との対応は信頼性に欠ける。

     一般的なシステムと例外的なシステムの両者が、2012-06-30 23:59:60 UTC の閏秒をどのように処理しているかを以下に示す。

          # 一般的なシステムは閏秒を無視する:
          date --date='2012-06-30 23:59:59 +0000' +%s
          1341100799
          date --date='2012-06-30 23:59:60 +0000' +%s
          date: invalid date '2012-06-30 23:59:60 +0000'
          date --date='2012-07-01 00:00:00 +0000' +%s
          1341100800

          # 例外的なシステムは閏秒をカウントする:
          date --date='2012-06-30 23:59:59 +0000' +%s
          1341100823
          date --date='2012-06-30 23:59:60 +0000' +%s
          1341100824
          date --date='2012-07-01 00:00:00 +0000' +%s
          1341100825

arch: マシンのハードウェア名を表示する
======================

arch は、マシンのハードウェア名を表示する。uname -m と同じことである。

書式:

     arch [OPTION]

このプログラムでは、共通オプションしか使用できない。Common options.

arch は、デフォルトではインストールされない。従って、移植を考慮したスクリプトでは、arch コマンドが存在することを当てにしない方がよい。

終了ステータス 0 は成功を示し、0 以外の値は失敗を示す。

nproc: 利用できるプロセッサの個数を表示する
=========================

カレントプロセスが利用できるプロセシング・ユニットの個数を表示する。それは、稼働しているプロセッサの数より少ないかもしれない。そうした情報が取得できない場合は、搭載されているプロセッサの数を表示する。環境変数 OMP_NUM_THREADS が設定されている場合は、その変数が、返される値を決めることになる。なお、結果は必ず 0 より大きくなる。

書式:

     nproc [OPTION]

このプログラムでは以下のオプションが使用できる。参照: Common options.

--all
     システムに搭載されているプロセッサの数を表示する。それは、稼働しているプロセッサや、カレントプロセスが利用できるプロセッサの数より多いかもしれない。このオプションを付けた場合、環境変数 OMP_NUM_THREADS は考慮されない。

--ignore=NUMBER
     可能ならば、NUMBER 個のプロセシング・ユニットを除外する。

終了ステータス 0 は成功を示し、0 以外の値は失敗を示す。

uname: システムについて情報を表示する
======================

uname は、自分がその上で実行されているマシンとオペレーティング・システムについて情報を表示する。オプションが一つも指定されない場合は、-s オプションが指定されたかのように振る舞う。

書式:

     uname [OPTION]...

複数のオプションや -a オプションが指定された場合、選択された情報は次の順番で表示される。

     KERNEL-NAME NODENAME KERNEL-RELEASE KERNEL-VERSION
     MACHINE PROCESSOR HARDWARE-PLATFORM OPERATING-SYSTEM

個々の情報が空白を含んでいることがある。そうした場合、出力のどこからどこまでが、ある情報に当たるかを判断することは難しい。以下の例で RELEASE に当たるのは、2.2.18 #4 SMP Tue Jun 5 11:24:08 PDT 2001 の部分である。

(訳注: RELEASE が KERNEL-RELEASE のことならば、それに相当するのは 2.2.18 だけである。#4 から 2001 までは KERNEL-VERSION。原文は両者を合わせて、RELEASE と言っているのかもしれない。なお、以下の例はちょっと古い。最近の uname -a では、-a オプションの説明にあるように、unknown の部分は表示されないはずである。)

     uname -a
     => Linux dumdum 2.2.18 #4 SMP Tue Jun 5 11:24:08 PDT 2001 i686
      unknown unknown GNU/Linux

このプログラムでは以下のオプションが使用できる。参照: Common options.

-a
--all
     以下の情報をすべて表示する。ただし、プロセッサ・タイプとハードウェア・プラットホームは、unknown ならば省略する。

-i
--hardware-platform
     ハードウェア・プラットホームの名前を表示する (ハードウェア実装と呼ばれることもある)。その情報が取得できない場合は、unknown と表示する。このオプションは、(GNU/Linux ディストリビューション同士の間ですら) 可搬性がない。

-m
--machine
     マシンのハードウェア名を表示する (ハードウェア・クラスとかハードウェア・タイプと呼ばれることもある)。

-n
--nodename
     ネットワークノードのホスト名を表示する。

-p
--processor
     プロセッサ・タイプを表示する (命令セット体系、the instruction set architecture、ISA などと呼ばれることもある)。その情報が取得できない場合は、unknown と表示する。このオプションは、(GNU/Linux ディストリビューション同士の間ですら) 可搬性がない。

-o
--operating-system
     オペレーティング・システムの名前を表示する。

-r
--kernel-release
     カーネルのリリース名を表示する。

-s
--kernel-name
     カーネル名を表示する。POSIX 1003.1-2001 では (see Standards conformance)、これを「オペレーティング・システムの実装」と呼んでいる。 POSIX の仕様には、カーネルという概念がないからである。カーネル名は、-o や  --operating-system オプションで表示されるオペレーティング・システム名と同じかもしれないし、違うかもしれない。オペレーティング・システムによって、基盤となっているカーネルと名前が同じものもあれば (FreeBSD, HP-UX など)、違うものもある (GNU/Linux, Solaris など) からである。

-v
--kernel-version
     カーネルのバージョンを表示する。

終了ステータス 0 は成功を示し、0 以外の値は失敗を示す。

hostname: システムの名前を表示、または設定する
============================

hostname は、引数なしで実行すると、使用しているホストシステムの名前を表示する。引数を一つ付けて実行すると、指定した文字列を使用しているホストの名前として設定する。ホストの名前を設定するには、しかるべき権限が必要である。

書式:

     hostname [NAME]

オプションは、--help と --version だけである。 See Common options.

hostname は、デフォルトではインストールされない。また、coreutils 以外のパッケージにも hostname コマンドを提供するものがある。従って、移植を考慮したスクリプトでは、hostname コマンドが存在することや、上記通りの動作をすることを当てにしない方がよい。

終了ステータス 0 は成功を示し、0 以外の値は失敗を示す。

hostid: 数値によるホストの識別名を表示する
=========================

hostid は、使用しているホストの数値による識別名を 16 進数で表示する。このコマンドは引数を取らない。使用できるオプションは、--help と --version だけである。See Common options.

たとえば、筆者が使っているシステムの一つでは、次のように表示される。

     $ hostid
     1bac013d

たまたまこのシステムでは、識別名の 32 ビットの数値が、システムのインターネット・アドレスと密接な関係を持っているが、いつでもそうとはかぎらない。

hostid がインストールされるのは、gethostid 関数が存在するシステムだけである。従って、移植を考慮したスクリプトでは、hostid の存在を当てにしない方がよい。

終了ステータス 0 は成功を示し、0 以外の値は失敗を示す。

uptime: システムの連続稼働時間と負荷を表示する
===========================

uptime は、現在の時刻、システムの連続稼働時間、ログインしているユーザの数、それに現在の平均負荷 (load average) を表示する。

引数を指定すると、ユーザが何人ログインしているかを知るために読み込むファイルとして、その引数が使用される。引数を指定しない場合は、システムのデフォルトが使用される (uptime --help を実行すれば、デフォルトの設定がわかる)。

オプションは、--help と --version だけである。 See Common options.

たとえば、以下の例は、筆者が使っているシステムの一つで、ちょうど今表示されたものだ。

     $ uptime
      14:07  up   3:35,  3 users,  load average: 1.39, 1.15, 1.04

細かいことを言うと、平均負荷の計算方法は、システムによっていくらか異なっている。あるシステムでは、ここ 1 分間、5 分間、15 分間の、実行可能状態のプロセスの平均数として計算されるが、別のシステムでは、割り込み不可能なスリープ状態のプロセスも含めている (すなわち、ディスク I/O を待っているプロセスだ)。 Linux のカーネルは、割り込み不可能なプロセスを含める方である。

uptime がインストールされるのは、ブート日時を取得するための下部構造を備えているプラットフォームだけである。また、coreutils 以外のパッケージにも、uptime コマンドを提供しているものがある。従って、移植を考慮したスクリプトでは、uptime コマンドが存在することや、上記通りの動作をすることを当てにしない方がよい。

終了ステータス 0 は成功を示し、0 以外の値は失敗を示す。

SELinux コンテキスト
**************

この章では、SELinux コンテキスト関係の操作を行うコマンドを説明する。

chcon: ファイルの SELinux コンテキストを変更する
================================

chcon は、指定されたファイルの SELinux セキュリティ・コンテキストを変更する。

書式:

     chcon [OPTION]... CONTEXT FILE...
     chcon [OPTION]... [-u USER] [-r ROLE] [-l RANGE]
      [-t TYPE] FILE...
     chcon [OPTION]... --reference=RFILE FILE...

各 FILE の SELinux セキュリティ・コンテキストを CONTEXT に変更する。 --reference オプションを使用した場合は、各 FILE のセキュリティ・コンテキストを RFILE のそれに変更する。

このプログラムでは以下のオプションが使用できる。参照: Common options.

--dereference
     シンボリックリンクそのものではなく、リンクが指しているものを操作の対象にする。これがデフォルトである。

-h
--no-dereference
     参照先のファイルではなく、シンボリックリンクそのものを操作の対象にする。

--reference=RFILE
     CONTEXT の値を直接指定する代わりに、RFILE のセキュリティ・コンテキストを使用する。

-R
--recursive
     ファイルやディレクトリに対して再帰的に動作する。

--preserve-root
     --recursive オプションと一緒に使ったとき、ルートディレクトリ (/) に対して再帰的に動作することを拒否する。 See Treating / specially.

--no-preserve-root
     --recursive オプションと一緒に使ったとき、ルートディレクトリ (/) を特別扱いしない。こちらがデフォルトの動作である。 See Treating / specially.

     See Traversing symlinks.

     See Traversing symlinks.

     See Traversing symlinks.

-v
--verbose
     処理したすべてのファイルについてメッセージを表示する。

-u USER
--user=USER
     操作対象のセキュリティ・コンテキストのユーザを USER にする。

-r ROLE
--role=ROLE
     操作対象のセキュリティ・コンテキストのロールを ROLE にする。

-t TYPE
--type=TYPE
     操作対象のセキュリティ・コンテキストのタイプを TYPE にする。

-l RANGE
--range=RANGE
     操作対象のセキュリティ・コンテキストのセキュリティ・レベルの範囲を RANGE にする。

終了ステータス 0 は成功を示し、0 以外の値は失敗を示す。

runcon: 指定された SELinux コンテキストでコマンドを実行する。
=======================================

runcon は、指定された SELinux セキュリティ・コンテキストでファイルを実行する。

書式:

     runcon CONTEXT COMMAND [ARGS]
     runcon [ -c ] [-u USER] [-r ROLE] [-t TYPE]
      [-l RANGE] COMMAND [ARGS]

セキュリティ・コンテキストのすべてを CONTEXT で指定して、COMMAND を実行する。あるいは、現在の、または遷移後のセキュリティ・コンテキストのうち、ユーザ、ロール、タイプ、レベルの一つ以上を変更して、COMMAND を実行する。

-c, -u, -r, -t, -l のどのオプションも指定されていない場合は、最初の引数が完全なコンテキストとして使用される。 COMMAND の後ろに続く引数があれば、それはそのコマンドに対する引数と見なされる。

CONTEXT と COMMAND のどちらも指定されていない場合は、現在のセキュリティ・コンテキストを表示する。

このプログラムでは以下のオプションが使用できる。参照: Common options.

-c
--compute
     セキュリティ・コンテキストの変更を行う前に、プロセスの遷移によるコンテキストを求める。

-u USER
--user=USER
     操作対象のセキュリティ・コンテキストのユーザを USER にする。

-r ROLE
--role=ROLE
     操作対象のセキュリティ・コンテキストのロールを ROLE にする。

-t TYPE
--type=TYPE
     操作対象のセキュリティ・コンテキストのタイプを TYPE にする。

-l RANGE
--range=RANGE
     操作対象のセキュリティ・コンテキストのセキュリティ・レベルの範囲を RANGE にする。

終了ステータス:

     126: COMMAND が見つかったが、起動できなかった。
     127: runcon そのものの実行に失敗した。あるいは、COMMAND が
          見つからなかった。
     それ以外は、COMMAND の終了ステータス。

コマンド実行条件の変更
***********

この章で説明するコマンドは、他のコマンドを現在の条件とは違った条件で実行するものである。たとえば、環境を変更して実行する、別のユーザとして実行するといったコマンドだ。

(訳注:　「別のユーザとして実行する」というのは、chroot の --userspec オプションを指していると考えられなくもないが、元々は su コマンドのことを言っていたのだと思う。 su も以前はこの章で説明されていたが、現在では coreutils に収録されていない。)

chroot: ルートディレクトリを変更して、コマンドを実行する
================================

chroot は、指定されたディレクトリをルートディレクトリにして、コマンドを実行する。多くのシステムでは、この操作を行うことができるのはスーパーユーザだけである。 (もっとも、システムによっては (たとえば、FreeBSD がそうだが)、特定の一般ユーザが chroot システムコールを使用できるように設定できるものもある。従って、そうしたユーザは chroot コマンドを実行できるわけだ。また、Cygwin では、どんなユーザでも chroot コマンドを実行できる。 MS-Windows が chroot 関数をサポートしていないため、内部で使用する関数が特権とは無関係だからである。なお、NEWROOT が元の / ディレクトリと同じ場合、chroot コマンドは chroot システムコールを使わないで済まそうとする。これは、非特権ユーザにもそうしたことが許されているシステムとの一貫性を保つためである。)

書式:

     chroot OPTION NEWROOT [COMMAND [ARGS]...]
     chroot OPTION

通常、ファイル名の検索は、ディレクトリ構造の根 (ルート、root)、すなわち / を起点として行われる。chroot はこのルートを NEWROOT ディレクトリ (実在するディレクトリでなければならない) に変更し、さらに、作業ディレクトリを / に変更して、最後に COMMAND を、ARGS の指定があれば ARGS を付けて実行する。 COMMAND が指定されていない場合、デフォルトのコマンドは、環境変数 SHELL の値か、SHELL が設定されていなければ、/bin/sh であり、それが -i オプションを付けて、呼び出される。 COMMAND は シェルの組み込みコマンドであってはならない (see Special built-in utilities)。

このプログラムでは以下のオプションが使用できる。参照: Common options. オプションはオペランドの前に置かなければならない。

--groups=GROUPS
     このオプションを使えば、新しいプロセスが使用する補助 GROUPS を変更することができる。グループのリストの各項目 (名前でも ID 番号でもよい) は、コンマで区切られていなければならない。 --userspec オプションで自動的に行われる補助グループの照合をしないようにするには、 --groups='' を使用すればよい。

--userspec=USER[:GROUP]
     デフォルトでは、COMMAND は呼び出し側のプロセスと同じ資格情報を使って実行されるが、このオプションを使えば、COMMAND を別の USER の資格で実行することができる。別の基本 GROUP を指定することも可能だ。 USER が指定された場合、補助グループは、そのユーザについてシステムが設定しているリストと同じものになる。ただし、--groups オプションによって置き換えられる場合は別だ。

--skip-chdir
     ルートディレクトリを NEWROOT に変更した後で (すなわち chroot 環境中で)、作業ディレクトリを / に変更したくなかったら、このオプションを使えばよい。このオプションが使用できるのは、NEWROOT が元の / ディレクトリと同じときだけであり、従って、役に立つのは、 --groups や "--userspec と一緒に使い、元の作業ディレクトリに留まっていたい場合がほとんどである。

--userspec や --groups オプションによって行われるユーザ名やグループ名の照合は、 chroot 環境の外側と内側の両方で行われるが、chroot 環境の内側で成功した照合が優先される。ユーザやグループの指定で ID 番号を使うつもりならば、数字の前に + を付ければ、名前を ID 番号に還元するステップが行われないで済む。 See Disambiguating names and IDs.

chroot を使う上でよくある問題を避けることができるように、ちょっとした情報をいくつか挙げておく。まず簡単なことから言うと、COMMAND は、静的にリンクしたバイナリを指すようにした方がよい。もし、動的にリンクした実行ファイルを使用するのならば、共有ライブラリが新しいルートディレクトリ以下の適切な場所に存在するように、前もって準備しておく必要があるだろう。

たとえば、静的にリンクした ls の実行ファイルを作成して、 /tmp/empty に置けば、root ユーザとして次のようなコマンドを実行することができる。

     $ chroot /tmp/empty /ls -Rl /

出力はこんなふうになるだろう。

     /:
     total 1023
     -rwxr-xr-x 1 0 0 1041745 Aug 16 11:17 ls

もし、動的にリンクした実行ファイル、たとえば bash を使いたいならば、まず ldd bash を実行して、どんな共有オブジェクトファイルが必要かを調べることだ。それから、bash 自体のバイナリをコピーするだけでなく、ldd bash でリストされたファイルも、新しいルートディレクトリになるディレクトリ以下のしかるべき場所にコピーしておく。さらに、実行ファイルが何か他のファイルも必要としているなら (たとえば、データファイル、ステータスファイル、デバイスファイルなど)、それも適切な場所にコピーする。

chroot がインストールされるのは、chroot 関数を持つシステムだけである。従って、移植を考慮したスクリプトでは、chroot が存在することを当てにしない方がよい。

終了ステータス:

     125: chroot そのものの実行に失敗した。
     126: COMMAND は見つかったが、起動できなかった。
     127: COMMAND が見つからなかった。
     それ以外は、COMMAND の終了ステータス。

env: 変更した環境でコマンドを実行する
=====================

env は、環境を変更して、コマンドを実行する。

書式:

     env [OPTION]... [NAME=VALUE]...
     [COMMAND [ARGS]...]
     env

VARIABLE=VALUE という形のオペランドは、環境変数 VARIABLE の値を VALUE に設定する。VALUE は空っぽでも構わない (VARIABLE=)。変数の値を空に設定 (set) するのは、変数を破棄 (unset) するのとは別のことである。こうしたオペランドは、左から右へ評価されるので、二つのオペランドが同じ変数を対象にしている場合、前のものは無視される。

環境変数名は、空でもよいし、= と ASCII NUL 以外なら、どんな文字を含んでいても構わない。とは言え、変数名は、アンダースコア、数字、ASCII 文字のみから構成し、数字以外の文字で始めるようにした方が、賢明である。それ以外の名前だと、シェルなどのアプリケーションがうまく動作しないからだ。

= という文字を含まない最初のオペランドが、起動するプログラムであり、環境変数 PATH に従って、どこにあるかが検索される。残っている引数があれば、すべてそのプログラムに引数として渡される。起動するプログラムは、シェルの組み込みコマンドであってはならない (see Special built-in utilities)。

PATH に対する変更は、COMMAND のありかを検索する前に有効になる。そこで、PATH を短縮するときには、気をつけなければならない。 PATH を未定義にしたり、/bin のような重要なディレクトリを外したりすると、変更前と同じ動作にならないかもしれないからだ。

めったにないことだが、プログラムの名前に = という文字が含まれている場合、それを変数の指定と区別する唯一の方法は、COMMAND として仲介的なコマンドを使用し、その ARGS として問題のあるプログラム名を渡すことである。たとえば、./prog= が現在の PATH 中に存在する実行ファイルだとしよう。

     env prog= true
       # 環境変数 prog を空に設定して 'true' を実行する。
     env ./prog= true
       # 環境変数 ./prog を空に設定して 'true' を実行する。
     env -- prog= true
       # 環境変数 prog を空に設定して 'true' を実行する。
     env sh -c '\prog= true'
       # 'true' を引数にして 'prog=' を実行する。
     env sh -c 'exec "$@"' sh prog= true
       # これも 'prog=' を実行する。

環境変数の設定の後にコマンド名が指定されていない場合は、生成された環境が表示される。これは、COMMAND に printenv を指定するのと同じことである。

以下に例をいくつか挙げる。env に渡される環境は、LOGNAME=rms, EDITOR=emacs, PATH=.:/gnubin:/hacks からなっているものとする。

  * 現在の環境を出力する。

          $ env | LC_ALL=C sort
          EDITOR=emacs
          LOGNAME=rms
          PATH=.:/gnubin:/hacks

  * 環境を削減して、foo を実行する。foo が見つからないといけないので、 PATH だけは元のまま残している。

          env - PATH="$PATH" foo

  * LOGNAME=rms, EDITOR=emacs, PATH=.:/gnubin:/hacks からなる環境で foo を実行する。 foo には、シェルの組み込みコマンドではなく、ファイルシステム中で見つかった実行ファイルが必ず使用される。

          env foo

  * LOGNAME=foo, EDITOR=emacs, PATH=.:/gnubin:/hacks, DISPLAY=gnu:0 からなる環境で、nemacs を実行する。

          env DISPLAY=gnu:0 LOGNAME=foo nemacs

  * プログラム /energy/-- の実行を試みる (パスの検索でそれしか出てこないようにしている)。 -- というコマンドが存在する場合、環境は、LOGNAME=rms と PATH=/energy だけになり、引数には、e=mc2, bar, baz が使われる。

          env -u EDITOR PATH=/energy -- e=mc2 bar baz

このプログラムでは以下のオプションが使用できる。参照: Common options. オプションはオペランドの前に置かなければならない。

-0
--null
     各行の末尾に改行ではなく、ゼロバイト (ASCII NUL) を出力する。このオプションを使用すると、出力するデータの途中に改行が現れる場合でも、他のプログラムがその出力を解析できるようになる。

-u NAME
--unset=NAME
     変数 NAME が環境中にあれば、それを環境から削除する。

-
-i
--ignore-environment
     継承した環境を無視し、空っぽの環境から始める。

終了ステータス:

     0:   COMMAND が指定されなかったので、環境を出力した。
     125: env そのものの実行に失敗した。
     126: COMMAND は見つかったが、起動できなかった。
     127: COMMAND が見つからなかった。
     それ以外は、COMMAND の終了ステータス。

nice: niceness を変更して、コマンドを実行する
==============================

nice はプロセスの niceness を表示したり、niceness を変更してコマンドを実行したりする。 niceness は、プロセスがシステム中でどの程度優先的にスケジュールされるかに影響を及ぼす。 (訳注: niceness を「スケジューリング優先度」と訳さない理由については、三つほど下のパラグラフを御覧いただきたい。)

書式:

     nice [OPTION]... [COMMAND [ARG]...]

引数を指定しないと、nice は現在の niceness を表示する。引数に COMMAND を指定した場合は、niceness を調整して、その COMMAND を実行する。デフォルトでは、niceness が 10 増加する。

niceness の値は、最小が -20 で、最大が 19 である (値が小さければ、プロセスの優先度が高くなり、使えるリソースも多くなるが、その分、他のプロセスの動作が遅くなる。また、値が大きければ、プロセスの優先度が低くなり、自分自身の動作は遅くなるが、実行中の他のプロセスの速度に与える影響は小さくなる)。システムによっては、niceness の値の範囲がもっと広いものもあるし、反対に、上下限の制限がもっときついものもある。サポートされている範囲を越えた niceness を指定すると、サポートされている値の最小、または最大を使用しようとしているものと見なされる。

niceness をスケジューリング優先度 (scheduling priority) と混同してはならない。後者は、様々なスレッドをどういう序列で実行するかの予定を組む際に、その序列をアプリケーション側に決めさせるものである。優先度とは違って、niceness はスケジューラに対する単なるアドバイスにすぎず、スケジューラはそれを無視することができるのだ。また、用語について言うと、 POSIX は nice の動作を nice value という用語で定義している。この nice value は、ある niceness と 最小の niceness との間の負ではない差である。 nice コマンドは POSIX に準拠しているものの、この文書やエラーメッセージでは、従来の習慣との親和性を考慮して、 ``niceness'' という言葉を使っている。

COMMAND は、シェルの組み込みコマンドであってはならない (see Special built-in utilities)。

シェルの組み込み機能の nice やエイリアスのために、 nice に何の修飾も付けずに対話的に使ったり、スクリプトの中で使ったりすると、動作がここで述べているものとは違うことがあるかもしれない。シェルによる干渉を避けるためには、env 経由で nice を起動すればよい (すなわち、env nice ... のようにだ)。

注意: 現在動作中のプロセスの niceness を変更するには、renice コマンドを使う必要がある。

このプログラムでは、以下のオプションが使用できる。参照: Common options. オプションはオペランドの前に置かなければならない。

-n ADJUSTMENT
--adjustment=ADJUSTMENT
     コマンドの niceness を 10 ではなく、ADJUSTMENT 増加する。 ADJUSTMENT が負の数の場合、ユーザがしかるべき特権を持っていなければ、 nice は警告を発する。とは言え、警告を出すだけで、ADJUSTMENT として 0 が指定されたかのように振る舞う。

     互換性を考慮して、nice は -ADJUSTMENT というオプションの古い書式もサポートしている。だが、新しいスクリプトでは、-n ADJUSTMENT の方を使うべきである。

nice がインストールされるのは、 POSIX の setpriority 関数を持っているシステムだけである。従って、移植を考慮したシステムでは、非 POSIX のプラットフォームに nice コマンドがあることを当てにしない方がよい。

終了ステータス:

     0:   COMMAND が指定されなかったので、niceness を出力した。
     125: nice そのものの実行に失敗した。
     126: COMMAND が見つかったが、起動できなかった。
     127: COMMAND が見つからなかった。
     それ以外は、COMMAND の終了ステータス。

対話的ではないプログラムは、niceness を落として (訳注: すなわち、 niceness の値を増やして) 実行すると、都合のよいことがある。

     $ nice factor 4611686018427387903

nice は、現在の niceness を表示するので、nice を通して nice を起動すれば、それがどんな動作をするか、目の当たりに見ることができる。

デフォルトの動作は、niceness を 10 増加することである。

     $ nice
     0
     $ nice nice
     10
     $ nice -n 10 nice
     10

ADJUSTMENT は、現在の niceness からいくら増減するかということである。次の例では、最初の nice が、二番目の nice を niceness 10 で実行し、二番目の nice は、niceness をさらに 3 増やして、三番目の nice を実行している。

     $ nice nice -n 3 nice
     13

サポートされている範囲より大きい niceness を指定するのは、サポートされている最大値を指定するのと同じことである。

     $ nice -n 10000000000 nice
     19

特権ユーザだけが niceness の値を下げて、プロセスを実行できる。

     $ nice -n -1 nice
     nice: cannot set niceness: Permission denied
     0
     $ sudo nice -n -1 nice
     -1

nohup: ハングアップ・シグナルで終了しないコマンドを実行する
=================================

nohup を使って、COMMAND を実行すると、指定されたコマンドがハングアップ・シグナルを無視するようになる。従って、そのコマンドは、ユーザがログアウトした後でも、バックグラウンドで実行を継続することができる。

書式:

     nohup COMMAND [ARG]...

標準入力が端末の場合は、nohup から実行されているコマンドが端末を使用していると、端末で行われるセッションが誤解しないように、標準入力をリダイレクトする。さらに、標準入力の代わりになるファイルのファイル・ディスクリプタを読み込み不可にする。 nohup から実行されているコマンドが、誤って標準入力から読み込を行おうとした場合に、エラーメッセージを出すことができるようにするためである。このリダイレクションは GNU の拡張である。 GNU 以外のホストでも使うことを考えているプログラムでは、GNU の拡張を当てにせず、 nohup COMMAND [ARG]... 0>/dev/null を使えばよい。

標準出力が端末の場合、コマンドの標準出力は、(訳注: カレントディレクトリの) nohup.out というファイルに追加されて行く。そのファイルに書き込めない場合は、$HOME/nohup.out に追記されることになる。そのファイルにも書き込めない場合は、コマンドの実行が行われない。 nohup によって作成されるのが nohup.out であれ、 $HOME/nohup.out であれ、それは、ファイルの所有者にのみ読み書き可能なものになる。現在の umask の設定の影響は受けない。

標準エラーが端末の場合、コマンドの標準エラー出力は、基本的には標準出力 (リダイレクトされているかもしれない) と同じファイル・ディスクリプタにリダイレクトされる。ただし、標準出力がクローズされている場合には、標準エラーの端末への出力は、リダイレクトされることなく、直接 nohup.out や $HOME/nohup.out というファイルに追加される。どちらのファイルが使用されるかは、上述のとおりである。

コマンドの出力を nohup.out 以外のファイルに書き込みたければ、リダイレクトすればよい。たとえば、make の出力を make.log に書き込みたかったら、次のようにする。

     nohup make > make.log

nohup は、実行するコマンドを自動的にバックグラウンドに送ることをしない。そこで、ユーザは、コマンドラインの末尾に & を付けることで、明示的にそれを行わなければならない。また、nohup は、COMMAND の niceness を変更しない。niceness を変更したかったら、nice を使って、nohup nice COMMAND のように実行すればよい。

COMMAND は、シェルの組み込みコマンドであってはならない (see Special built-in utilities)。

指定できるオプションは、--help と --version だけである。 See Common options.  オプションはオペランドの前に置かなければならない。

終了ステータス:

     125: POSIXLY_CORRECT が設定されていない場合に、nohup そのものの
           実行に失敗した。
     126: COMMAND は見つかったが、起動できなかった。
     127: COMMAND が見つからなかった。
     それ以外の場合は、COMMAND の終了ステータス。

POSIXLY_CORRECT が設定されている場合は、nohup そのものが実行に失敗したときの終了ステータスは、125 ではなく 127 になる。

stdbuf: 入出力ストリームのバッファリングを変更して、コマンドを実行する
=======================================

stdbuf を使用すると、プログラムと結びついている 3 種類の標準入出力ストリームに対して、そのバッファリング動作を変更することができる。

書式:

     stdbuf OPTION... COMMAND

COMMAND は、次の条件を満たすプログラムの名前で始まっていなければならない。

 1. 入出力に ISO C FILE ストリームを使用している (注意: プログラム dd や cat は、これを使用していない)。

 2. 自分で標準ストリームのバッファリングを調整していない (注意: プログラム tee は、この部類に入らない)。

後に続く引数があれば、COMMAND に引数として渡される。

このプログラムでは以下のオプションが使用できる。参照: Common options.

-i MODE
--input=MODE
     標準入力ストリームのバッファリングを調整する。

-o MODE
--output=MODE
     標準出力ストリームのバッファリングを調整する。

-e MODE
--error=MODE
     標準エラーストリームのバッファリングを調整する。

MODE には、以下のものを指定できる。

L
     ストリームを行単位のバッファ・モードにする。このモードでは、改行が出力されることになるか、あるいは、端末デバイスに結びついているストリームから入力が読み込まれるまで、データを溜めておく。このオプションは、標準入力に対しては無効である。

0
     選択したストリームのバッファリングを無効にする。このモードでは、データは即座に出力される。また、要求された量のデータしか入力から読み込まない。入力と出力で動作が違うことに気をつけていただきたい。なお、入力のバッファリングを無効にしても、ストリーム入力関数の応答性やブロッキング動作に影響することはない。たとえば、fread は、要求した量より少ないデータを、下層で動いている read が返してきても、EOF が来るか、エラーが起きるまで、やはりブロッキングを行うのである。

SIZE
     バッファ一杯モード (fully buffered mode) で使用するバッファのサイズを指定する。 SIZE は、整数であり、以下に挙げるような何倍かを示す接尾辞を後ろに付けることもできる。接尾辞だけ指定してもよい (訳注: その場合は、1 が前にあるものと見なされる)。

          KB =>           1000 (KiloBytes)
          K  =>           1024 (KibiBytes)
          MB =>      1000*1000 (MegaBytes)
          M  =>      1024*1024 (MebiBytes)
          GB => 1000*1000*1000 (GigaBytes)
          G  => 1024*1024*1024 (GibiBytes)

     T, P, E, Z, Y についても同様。

stdbuf がインストールされるのは、Executable and Linkable Format (ELF) を使用し、constructor アトリビュートをサポートしているプラットフォームだけである。従って、移植を考慮したスクリプトでは、stdbuf が存在することを当てにしない方がよい。

終了ステータス:

     125: stdbuf そのものの実行に失敗した。
     126: COMMAND は見つかったが、起動できなかった。
     127: COMMAND が見つからなかった。
     それ以外は、COMMAND の終了ステータス。

timeout: タイムリミット付きでコマンドを実行する
============================

timeout は渡されたコマンドを実行し、指定された時間が経過してもまだ実行が続いていたら、そのコマンドを終了させる。

書式:

     timeout [OPTION] DURATION COMMAND [ARG]...

COMMAND は、シェルの組み込みコマンドであってはならない (see Special built-in utilities)。

このプログラムでは以下のオプションが使用できる。参照: Common options. オプションはオペランドの前に置かなければならない。

--preserve-status
     タイムアウトしたときに、タイムアウトであることを示す timeout コマンドの終了ステータスではなく、timeout が管理している COMMAND の終了ステータスを返す。このオプションは、管理される COMMAND が無期限の続行時間をサポートしている場合に役に立つ。

--foreground
     独立したバックグラウンドのプログラム・グループを作成しない。その結果、timeout に管理される COMMAND が、フォアグラウンドの TTY を通常どおり使用できるようになる。対話的シェルから直接実行されないコマンドの時間制限をきちんと行うには (訳注: 言い換えれば、timeout コマンドをシェルスクリプト中で使用する場合には)、この動作が必要になることがあり、次の二つの場合がそれに当たる。

      1. COMMAND が対話的であり、たとえば端末からの読み込みが必要な場合。

      2. 端末から直接 COMMAND にシグナルを送ることができるようにしたい場合。 (たとえば、Ctrl-C を送るとか)。

     気をつけていただきたいが、この動作モードでは、COMMAND の子プロセスは、いかなるものもタイムアウトすることがない。また、SIGCONT シグナルが COMMAND に送られることもない。フォアグラウンドプロセスでは、そういったことは普通必要がないからであり、また、(たとえば、GDB のような) それ自身が他のプログラムを監視するモニターであるプログラムでは、断続的なシグナル送出を起こしかねないからである。

-k DURATION
--kill-after=DURATION
     ここで指定した DURATION の経過後に、改めて KILL シグナルを送り付けて、監視対象の COMMAND を確実に終了させる。このオプションを付けないと、選択したシグナルに COMMAND を終了させる力がなかった場合に、timeout は COMMAND を殺すことができない。

-s SIGNAL
--signal=SIGNAL
     制限時間が来たとき、デフォルトの TERM シグナルではなく、指定した SIGNAL を COMMAND に送る。SIGNAL は HUP のような名前でもよく、番号でもよい。See Signal specifications.

DURATION は浮動小数点数であり、後ろに単位を付けることもできる。

     s 何秒 (デフォルト)
     m 何分
     h 何時間
     d 何日

DURATION が 0 だと、対象となるコマンドが時間切れなしになる。実際の制限時間は、システムの制約を受けることに注意していただきたい。秒以下の制限時間を指定するときは、とりわけそれを考慮に入れるべきである。

終了ステータス:

     124: COMMAND がタイムアウトした。
     125: timeout そのものの実行に失敗した。
     126: COMMAND は見つかったが、起動できなかった。
     127: COMMAND が見つからなかった。
     137: COMMAND に KILL(9) シグナルを送った (128+9)
     それ以外は、COMMAND の終了ステータス。

プロセス制御
******

kill: プロセスにシグナルを送る
==================

kill コマンドは、プロセスにシグナルを送る。シグナルを送られたプロセスは、終了するか、あるいは、シグナルを受け取った時点で他の何らかの形で反応する。また、kill は、シグナルに関する情報を一覧表示する。

書式:

     kill [-s SIGNAL | --signal SIGNAL | -SIGNAL] PID...
     kill [-l | --list | -t | --table] [SIGNAL]...

シェルの組み込み機能の kill やエイリアスのために、 kill に何の修飾も付けずに対話的に使ったり、スクリプトの中で使ったりすると、動作がここで述べているものとは違うことがあるかもしれない。シェルによる干渉を避けるためには、env 経由で kill を起動すればよい (すなわち、env kill ... のようにだ)。

kill コマンドの最初の書式では、すべての PID 引数に対してシグナルが送られる。シグナルが指定されていない場合に送られるデフォルトのシグナルは、TERM である。 0 という特別なシグナル番号は、有効なシグナルを表していないが、引数 PID が指しているプロセスに対してシグナルを送ることが可能かどうかを、調べるために使うことができる。

PID が正の数なら、シグナルはプロセス ID が PID のプロセスに送られる。 PID が 0 なら、シグナルはカレントプロセスのプロセスグループに属するすべてのプロセスに送られる。 PID が -1 の場合、シグナルが送られるのは、ユーザがシグナルを送る権限を持っているすべてのプロセスである。 PID が -1 より小さい場合は、PID の絶対値に等しいプロセスグループに属するすべてのプロセスにシグナルが送られる。

PID が正の数ではない場合、システムプロセスに属するプロセス (システムによって様々である) は、シグナルが送られるプロセスのリストから除外される。

最初の PID 引数として負の PID を使用したい場合は、その前に -- オプションを置くべきである。とは言え、kill -SIGNAL -PID という書式を使う場合は、 -- は必要がない。これは、POSIX に対する一般的な拡張である。そこで、次に挙げるコマンドは等価になる。

     kill -15 -1
     kill -TERM -1
     kill -s TERM -- -1
     kill -- -1

最初の書式の kill コマンドは、すべての PID 引数が、シグナルが送られたプロセスをそれぞれ少なくとも一つは指している場合に、成功のステータスで終了する。

kill コマンドの二番目の書式では、シグナルに関する情報が表示される。 -l または --list、あるいは、-t または --table オプションの指定は必須である。引数 SIGNAL を一つも指定しないと、サポートされているすべてのシグナルがリストされる。-l や --list の出力は、シグナル名のリストであり、1 行に一つづつ表示される。ただし、引数 SIGNAL がすでにシグナル名である場合は、名前ではなく、シグナル番号の表示になる。 -t や --table の出力は、シグナル番号、シグナル名、その説明からなる表である。この書式の kill コマンドは、引数として指定されたすべての SIGNAL が有効なものであり、出力エラーがなかったとき、成功のステータスで終了する。

kill コマンドでは、--help や --version オプションも使用できる。 See Common options.

SIGNAL の指定には、HUP のようなシグナル名や、1のようなシグナル番号、それに、シグナルによって終了させられるときのプロセスの終了ステータスを使うことができる (訳注: 最後のものは、GNU coreutils の kill コマンドでは使用できるが、シェルの組み込みコマンドのような、他の系統の kill では使えないかもしれない)。シグナル名は、標準的な形式でも、頭に SIG を付けた形式でも構わない。大文字小文字はどちらを使ってもよいが、-SIGNAL という形式のオプションの場合は例外で、大文字を使わなければならない。小文字を使うと、他のオプションとまぎらわしいからである。サポートしているシグナル名とシグナル番号については、「2.5 シグナルの指定」を参照していただきたい。 See Signal specifications.

一時停止
****

sleep: 指定された時間、停止する
===================

sleep は、コマンドラインで引数として指定された値を合計した時間だけ停止する。

書式:

     sleep NUMBER[smhd]...

各引数は数値であり、後ろに単位を付けてもよい。デフォルトの単位は秒である。単位には、以下のものが指定できる。

s
     秒

m
     分

h
     時

d
     日

sleep の従来の実装では、NUMBER は整数でなければならず、引数は接尾辞なしのものが 1 個しか認められていなかった。それに対して GNU の sleep では、任意の浮動小数点数を複数個指定できる。 See Floating point.

オプションは、--help と --version だけである。 See Common options.

シェルの組み込み機能の sleep やエイリアスのために、 sleep に何の修飾も付けずに対話的に使ったり、スクリプトの中で使ったりすると、動作がここで述べているものとは違うことがあるかもしれない。シェルによる干渉を避けるためには、env 経由で sleep を起動すればよい (すなわち、env sleep ... のようにだ)。

終了ステータス 0 は成功を示し、0 以外の値は失敗を示す。

数値の操作
*****

以下のプログラムは、数に関係した作業をする。

factor: 素因数を表示する
================

factor は、素因数を表示する。

書式:

     factor [NUMBER]...
     factor OPTION

NUMBER がコマンドラインで指定されていない場合、factor は標準入力から数値を読み込む。このとき、改行、タブ、空白で区切って複数の数値を入力することができる。

factor コマンドで使えるオプションは、いくつもない。

--help
     簡単なヘルプメッセージを標準出力に表示し、それ以上の処理をせずに終了する。

--version
     プログラムのバージョンを標準出力に表示し、それ以上の処理をせずに終了する。

メルセンヌ素数の 8 番目と 9 番目の積を素因数に分解するには、2.2 GHz Athlon のシステムで、30 ミリセコンドの CPU 時間を要する。

     M8=$(echo 2^31-1|bc)
     M9=$(echo 2^61-1|bc)
     n=$(echo "$M8 * $M9" | bc)
     /usr/bin/time -f %U factor $n
     4951760154835678088235319297: 2147483647 2305843009213693951
     0.03

同様に、8 番目のフェルマー数、2^256+1 では、同じマシンで約 20 秒かかる。

大きな数の素因数分解は、そもそも大変な作業である。factor が使用している Pollard-Brent rho アルゴリズムは、比較的小さな因数を持つ数値に対してとりわけ効率がよい。もし、小さな因数を持たない大きな数値 (たとえば、二つの大きな素数の積からなる数値) の素因数分解をなさりたいのなら、他の方法の方がずっとすぐれている。

factor が GNU MP を使用せずにビルドされている場合は、単精度の算術しか利用できない。従って、大きな数値 (一般には 2^128 以上) には対応していない。単精度用のコードが使用しているアルゴリズムは、比較的小さな数値を素因数に分解するためのものなのである。

終了ステータス 0 は成功を示し、0 以外の値は失敗を示す。

numfmt: 数値を整形し直す
================

numfmt はさまざまな表記の数値を読み込んで、それを要求された形に整形し直す。一番よく使うのは、数値を人間が読みやすい形に変換する場合や、その逆を行う場合である (たとえば、4G ==> 4,000,000,000)。

     numfmt [OPTION]... [NUMBER]

numfmt は、コマンドラインで与えられた各 NUMBER を、指定されたオプション (以下の節を参照) に従って変換する。 NUMBER の指定がない場合は、標準入力から数値を読み込む。また、numfmt は、入力行中の特定のフィールドから数値を取り出すこともできる。その場合、列が揃うようにパディング (訳注: フィールドの空き埋め) が行われていれば、それも適切に維持する。

終了ステータス 0 は成功を示し、0 以外の値は失敗を示す。

終了ステータスについては追加情報がある。--invalid をご覧になっていただきたい。

一般オプション
-------

このプログラムでは以下のオプションが使用できる。参照: Common options.

--debug
     間違えた使い方をしている疑いがあるとき、それについて警告メッセージを (標準エラーに) 表示する。

-d D
--delimiter=D
     文字 D を入力フィールドの区切りとして使用する (デフォルトはホワイトスペース)。区切りにデフォルト以外の文字を使うと、自動的なパディングが行われなくなるのに注意していただきたい。

--field=FIELDS
     FIELD 番目の入力フィールドの数値を変換する (FIELD のデフォルトは 1)。 FIELDS では、cut と同じような範囲指定が使える。

          N    N 番目のフィールド、1 から数える
          N-   N 番目のフィールドから行末まで
          N-M  N 番目から M 番目のフィールドまで (両端を含む)
          -M   行頭から M 番目のフィールドまで (両端を含む)
          -    すべてのフィールド

--format=FORMAT
     浮動小数点数を表す printf 形式の FORMAT 文字列を出力の整形に使用する。文字列 FORMAT には、1 個の %f 変換指定子が含まれていなければならない。なお、そうしたければ、', -, 0 といった修飾子や、フィールド幅修飾子 (訳注: 数値)、精度修飾子を %f に付けることもできる。 ' 修飾子は --grouping オプションを有効にし、- 修飾子は --padding オプションを左詰めで有効に、フィールド幅修飾子は --padding オプションを右詰めで有効にする (訳注: - 修飾子は、数値であるフィールド幅修飾子と併せて用いなければならない)。 0 フィールド幅修飾子を使うと (- も同時に指定されていなければ)、指定された幅になるまで数値の前に 0 を付けることになる。 %.1f のような精度指定は、入力データから引き出される精度や、--to オプションを使用したときの、数値の大きさや桁数の自動調整 (auto-scaling) によって決められた精度を上書きする。

--from=UNIT
     入力された数値の大きさや桁数を UNIT に従って自動調整 (auto-scaling) する (訳注: 一例を挙げると、入力数値が 1K だったとき、--from=si が指定されていれば 1000 に変換し、--from=iec が指定されていれば 1024 に変換する)。UNIT については、次節「使用できる UNIT」を参照していただきたい。デフォルトでは数値の大きさや桁数の調節を行わない。それはまた、入力数値に接尾辞 (たとえば、M, G など) が付いていると、エラーになるということでもある。

--from-unit=N
     入力の 1 単位の大きさを (すなわち、デフォルトの 1 に代えて使う大きさを) 指定する。入力する数値の 1 単位の大きさが、デフォルトの 1 以外の場合に、このオプションを使用するわけだ (たとえば、入力する数値の 10 が、1 単位 512 バイトの 10 単位を表している場合には、 --from-unit=512 を使用する)。単位となる数値に接尾辞を付けると、--from=auto の場合と同様に処理される。

--grouping
     現在のロケールの桁区切りルールに従って、出力する数値を数桁ごとに区切る (たとえば、3 桁ごとの区切り記号は、たいてい . (ドット) か , (コンマ) である)。ロケールが POSIX/C の場合は、このオプションに効果はない。

--header[=N]
     最初の N (デフォルトは 1) 行を、いかなる変換もせずに出力する。

--invalid=MODE
     入力エラーに出会ったときのデフォルトの動作は、ステータスコード 2 で即座に終了することである。 --invalid=abort は、このデフォルトの動作を明示的に指定することになる。 MODE に fail を指定すると、変換エラーがあるごとに警告メッセージを表示して、ステータス 2 で終了する。 MODE が warn の場合は、変換エラーがあっても、ステータス 0 で終了する。MODE が ignore の場合は、ステータス 0 で終了するだけでなく、診断メッセージを出すことすらしない。

--padding=N
     出力する数値が N 字分を占めるように、スペースを加えることでパディングを行う。 N が正の数の場合は、数値が右詰めになり、負の数の場合は、数値が左詰めになる。デフォルトでは、数値は、入力行の幅に基づいて (訳注: 詳しく言うと、入力各行の変換する数値のあるフィールドが固定幅の場合、その幅を使用して) 自動的に揃えられる (ただし、それが行われるのは、フィールドの区切り文字がデフォルトの場合だけである)。

--round=METHOD
     数値の表現を変換するときに、METHOD に従って、数値を丸める。METHOD には、up, down, from-zero (デフォルト), towards-zero, nearest が使用できる。(訳注: up は切り上げ、down は切り下げ、 from-zero はゼロから離れる方向へ、towards-zero はゼロに近づく方向へ、 nearest は四捨五入である。)

--suffix=SUFFIX
     出力する数値に SUFFIX を付ける。また、入力する数値に SUFFIX が付いていても、エラーにしない。

--to=UNIT
     出力する数値の大きさや桁数を UNIT に従って自動調整する。 UNIT については、次節「使用できる UNIT」を参照していただきたい。デフォルトでは、数値の大きさや桁数の調節をしないので、数値を構成するすべての数字が表示されることになる。

--to-unit=N
     出力の 1 単位の大きさを (すなわち、デフォルトの 1 に代えて使う大きさを) 指定する。出力する数値の 1 単位の大きさが、デフォルトの 1 以外の場合に、このオプションを使用するわけだ (たとえば、1 ブロック 1KB のブロック数で 4,000,000 バイトを表現するには、 --to=si --to-unit=1000 が使用できる)。単位となる数値に接尾辞を付けると、--from=auto の場合と同様に処理される。

     -z オプションを使用した場合、改行文字はフィールド・セパレータ扱いになる。

使用できる UNIT
----------

--from=UNIT や --to=UNIT で指定する UNIT には、次のものを選択することができる。(訳注: UNIT の名前は、大文字ではなく、si, iec などの小文字で指定すること。)

none
     数値の大きさや桁数の調整を行わない。入力する数値には、いかなる接尾辞も付けることができない。従って、数値の直後に文字が続くとエラーになる。出力する数値については、その数値を構成するすべての数字を表示する。

si
     国際単位系 (International System of Units (SI)) の規格に従って、数値の大きさや桁数を自動調整する。入力する数値には、以下の接尾辞の一つが使用できる。出力する数値については、1000 以上の値は丸められて、以下の接尾辞の一つを付けて表示される。

          K  =>  1000^1 = 10^3 (Kilo)
          M  =>  1000^2 = 10^6 (Mega)
          G  =>  1000^3 = 10^9 (Giga)
          T  =>  1000^4 = 10^{12} (Tera)
          P  =>  1000^5 = 10^{15} (Peta)
          E  =>  1000^6 = 10^{18} (Exa)
          Z  =>  1000^7 = 10^{21} (Zetta)
          Y  =>  1000^8 = 10^{24} (Yotta)

iec
     International Electrotechnical Commission (IEC) の規格に従って、数値の大きさや桁数を自動調整する。入力する数値では、以下の接尾辞の一つが使用できる。出力する数値については、1024 以上の値は丸められて、以下の接尾辞の一つを付けて表示される。

          K  =>  1024^1 = 2^{10} (Kibi)
          M  =>  1024^2 = 2^{20} (Mebi)
          G  =>  1024^3 = 2^{30} (Gibi)
          T  =>  1024^4 = 2^{40} (Tebi)
          P  =>  1024^5 = 2^{50} (Pebi)
          E  =>  1024^6 = 2^{60} (Exbi)
          Z  =>  1024^7 = 2^{70} (Zebi)
          Y  =>  1024^8 = 2^{80} (Yobi)

     iec を選択すると、接尾辞に (G など) 1 文字の記号が使用されることになるが、これは規格に完全にかなってるとは言えない。 IEC の規格では (Gi など) 2 字の記号を推奨しているからだ。しかし、実際の使用では、1 文字の表記法が普通に使われている。 iec-i を指定した場合と比較していただきたい。

iec-i
     International Electrotechnical Commission (IEC) の規格に従って、数値の大きさや桁数を自動調整する。入力する数値では、以下の接尾辞の一つが使用できる。出力する数値については、1024 以上の値は丸められて、以下の接尾辞の一つを付けて表示される。

          Ki  =>  1024^1 = 2^{10} (Kibi)
          Mi  =>  1024^2 = 2^{20} (Mebi)
          Gi  =>  1024^3 = 2^{30} (Gibi)
          Ti  =>  1024^4 = 2^{40} (Tebi)
          Pi  =>  1024^5 = 2^{50} (Pebi)
          Ei  =>  1024^6 = 2^{60} (Exbi)
          Zi  =>  1024^7 = 2^{70} (Zebi)
          Yi  =>  1024^8 = 2^{80} (Yobi)

     iec-i を選択すると、接尾辞に (Gi など) 2 文字の記号が使用されることになる。これは、IEC の規格が推奨しているとおりだが、実際の使用では、必ずしもよく使われているわけではない。iec を指定した場合と、比較していただきたい。

auto
     auto は --from でしか使えない。これを選んだ場合、K,M,G, T,P,E,Z,Y といった接尾辞が付いていれば、数値は SI の値と見なされる。接尾辞が Ki,Mi,Gi,Ti,Pi,Ei,Zi,Yi などの場合は、数値は IEC の値と見なされることになる。

nunfmt の使用例
-----------

1 個の数値を人間に読みやすい形に変換する (あるいは、その逆を行う)。

     $ numfmt --to=si 500000
     500K

     $ numfmt --to=iec 500000
     489K

     $ numfmt --to=iec-i 500000
     489Ki

     $ numfmt --from=si 1M
     1000000

     $ numfmt --from=iec 1M
     1048576

     # '--from=auto' を使用する。M=Mega, Mi=Mebi
     $ numfmt --from=auto 1M
     1000000
     $ numfmt --from=auto 1Mi
     1048576

SI 表記を IEC 表記に換算する (たとえば、ハードディスクの容量が、メーカー表示では 1TB となっているが、実際に容量をチェックすると、それより少ない場合)。

     $ numfmt --from=si --to=iec 1T
     932G

ファイルやパイプから読み込んだ入力行にある、ある一つのフィールドを変換する (ここに示す数例は、あくまでも説明のために作ったものである。実際には、ls と df のどちらにも、人間に読みやすい形式でサイズを表示するための --human-readable オプションが存在している)。

     # 3 番目のフィールド (ファイルサイズ) を SI 表記で表示する
     $ ls -log | numfmt --field 3 --header --to=si | head -n4
     -rw-r--r--  1     94K Aug 23  2011 ABOUT-NLS
     -rw-r--r--  1    3.7K Jan  7 16:15 AUTHORS
     -rw-r--r--  1     36K Jun  1  2011 COPYING
     -rw-r--r--  1       0 Jan  7 15:15 ChangeLog
     (訳注: 実際には、この一番下の行は表示されず、一番上に「total ...
     といった行が現れるはずである。)

     # 二番目のフィールド (サイズ) を IEC 表記で表示する
     $ df --block-size=1 | numfmt --field 2 --header --to=iec | head -n4
     File system   1B-blocks        Used  Available Use% Mounted on
     rootfs             132G   104741408   26554036  80% /
     tmpfs              794M        7580     804960   1% /run/shm
     /dev/sdb1          694G   651424756   46074696  94% /home

出力は --padding や --format オプションを使って加工することができる。

     # フィールド幅が 10 字になるまで空白で埋める。右詰め表示。
     $ du -s * | numfmt --to=si --padding=10
           2.5K config.log
            108 config.status
           1.7K configure
             20 configure.ac

     # フィールド幅が 10 字になるまで空白で埋める。左詰め表示。
     $ du -s * | numfmt --to=si --padding=-10
     2.5K       config.log
     108        config.status
     1.7K       configure
     20         configure.ac

     # --format オプションを使用して、フィールド幅が 10 文字になるまで
     # 空白で埋める。右詰め表示。
     $ du -s * | numfmt --to=si --format="%10f"
           2.5K config.log
            108 config.status
           1.7K configure
             20 configure.ac

     # --format オプションを使用して、フィールド幅が 10 文字になるまで
     # 空白で埋める。左詰め表示。
     $ du -s * | numfmt --to=si --padding="%-10f"
     2.5K       config.log
     108        config.status
     1.7K       configure
     20         configure.ac

桁区切りをサポートしているロケールでは、--grouping や --format オプションを使って、数値を数桁ごとに区切ることができる。ロケールが POSIX や C の場合は、桁区切りを指定しても、単に無視される。

     $ LC_ALL=C numfmt --from=iec --grouping 2G
     2147483648

     $ LC_ALL=en_US.utf8 numfmt --from=iec --grouping 2G
     2,147,483,648

     $ LC_ALL=ta_IN numfmt --from=iec --grouping 2G
     2,14,74,83,648

     $ LC_ALL=C numfmt --from=iec --format="==%'15f==" 2G
     ==     2147483648==

     $ LC_ALL=en_US.utf8 numfmt --from=iec --format="==%'15f==" 2G
     ==  2,147,483,648==

     $ LC_ALL=en_US.utf8 numfmt --from=iec --format="==%'-15f==" 2G
     ==2,147,483,648  ==

     $ LC_ALL=ta_IN numfmt --from=iec --format="==%'15f==" 2G
     == 2,14,74,83,648==

seq: 数列を表示する
============

seq は、数列を標準出力に表示する。

書式:

     seq [OPTION]... LAST
     seq [OPTION]... FIRST LAST
     seq [OPTION]... FIRST INCREMENT LAST

seq は、FIRST から LAST までの数を INCREMENT おきに表示する。デフォルトでは、それぞれの数は 1 行に 1 個づつ表示される。 INCREMENT が指定されていない場合は、FIRST が LAST より大きい場合でも、デフォルトの 1 が INCREMENT として使用される。 FIRST のデフォルトもまた 1 である。従って、seq 1 は 1 を表示するが、seq 0 や seq 10 5 は、何も出力しない。数列が終了するのは、現在の数値に INCREMENT を加えたら LAST より大きくなってしまう時点である。だから、seq 1 10 10 は、1 しか表示しない。INCREMENT の値には 0 を指定できない。同じ数を繰り返し出力したかったら、yes コマンドを使うべきである。また、FIRST, INCREMENT, LAST の値は、NaN (訳注: Not a Number) であってはならない。数値には浮動小数点数を指定することもできる。 See Floating point.

このプログラムでは以下のオプションが使用できる。参照: Common options. オプションはオペランドの前に置かなければならない。

-f FORMAT
--format=FORMAT
     すべての数を FORMAT を使用して表示する。FORMAT は、 printf 形式の浮動小数点数の変換指定をただ一つ含むものでなければならない。すなわち、%a, %e, %f, %g, %A, %E, %F, %G のいづれかである。 % の後ろには 0 個以上のフラグを、-+#0 ' のうちから選んで置くことができる。また、それに続けて、1 個以上の数字からなるフィールド幅を指定することもできるし、さらにその後ろに、. とそれに続く 0 個以上の数字からなる精度を指定することもできる。 FORMAT には、任意の数の %% 変換指定が含まれていてもよい。変換指定はすべて、printf の場合と同じ意味を持っている。

     デフォルトの表示形式は、FIRST, INCREMENT, LAST がどういう表記を使用しているかよって決まる。そのすべてが固定小数点の 10 進数表記を使用しているならば、デフォルトの表示形式は %.Pf になる。この P には、出力する数値を過不足なく表現できる最小の精度が来る。それ以外の場合、デフォルトの表示形式は %g になる。

-s STRING
--separator=STRING
     数の区切りに STRING を使う。デフォルトは改行である。出力の最後には、必ず改行が付く。

-w
--equal-width
     すべての数を同じ桁数で表示する。先頭の空きは 0 で埋める。FIRST, INCREMENT, LAST は、すべて固定小数点の 10 進数表記でなければならない (他のやり方で先頭を埋めたければ、--format を使うこと)。

-f オプションを使えば、出力をもっときめ細かく制御することができる。

     $ seq -f '(%9.2E)' -9e5 1.1e6 1.3e6
     (-9.00E+05)
     ( 2.00E+05)
     ( 1.30E+06)

出力を 16 進数の整数にしたかったら、printf を使って変換すればよい。

     $ printf '%x\n' $(seq 1048575 1024 1050623)
     fffff
     1003ff
     1007ff

数のリストが非常に長くなる場合は、xargs を使用すると、引数リストの長さに対するシステムの制限を回避することができる。

     $ seq 1000000 | xargs printf '%x\n' | tail -n 3
     f423e
     f423f
     f4240

8 進数の出力を生成するには、printf に対して %x の代わりに、%o フォーマットを使用すればよい。

ほとんどのシステムで seq は、少なくとも 2^53 までの数値に対して整数の出力を生成することができる。それより大きい整数に対しては概算になる。細かい点は、ご使用のシステムの浮動小数点の実装によって異なっている。 See Floating point.  seq が 2^64 までの整数に対してなら、きちんと動作するが、それより大きな整数に対しては、数値が不正確になることがあるというのは、よくある話である。

     $ seq 50000000000000000000 2 50000000000000000004
     50000000000000000000
     50000000000000000000
     50000000000000000004

とは言え、負ではない整数を対象とし、インクリメントが 1 で、フォーマット指定オプションはないという条件の元では、 seq は任意の大きな数値を表示できることも心に留めておいていただきたい。

seq でとんでもなく大きな桁の値を扱うときは、気をつけた方がよい。さもないと、seq は内部で浮動小数点を使用しているので、結果を見てびっくりするかもしれない。たとえば、x86 のプラットフォームでは、内部表現が 64 ビットの仮数部を使用しているが、そこで次のコマンドを実行すると、

     seq 1 0.0000000000000000001 1.0000000000000000009

seq は 1.0000000000000000007 を二度出力し、1.0000000000000000008 をスキップする (訳注: 訳者の amd64 環境では、1.0000000000000000008 ではなく、1.0000000000000000006 をスキップする)。

終了ステータス 0 は成功を示し、0 以外の値は失敗を示す。

ファイルの許可属性
*********

     [file perm-ja.texi not included]

     [file parse-datetime-ja.texi not included]

ソフトウェアの道具箱
**********

この章の初期のバージョンは、「GNU とは何か？ (What's GNU?)」という連載記事として Linux Journal 1994 年 6 月号に掲載された。執筆者は Arnold Robbins である。 (http://www.linuxjournal.com/article.php?sid=2762)

はじめに
====

今月の記事と GNU プロジェクトの関係は、周辺的なものにすぎない。お手元の GNU/Linux システムの GNU ツールをいくつか取り上げて、こんな使い方もありますよ、と述べている点で、関係があるにすぎないのだ。今月の記事の真の狙いは、プログラムを開発したり、使用したりする上での、「ソフトウェアは工具だ」という考え方を説明することである。

ソフトウェアは工具だという思想は、Unix が最初に設計され、開発されたときの重要で不可欠な考え方だった (Linux も GNU も本質的には Unix のクローンである)。残念なことに、最近ではインターネットや見栄えのよい GUI の勢いに押されて、ソフトウェア工具論は流行らなくなっているようだ。この思想は、様々な問題を解決するための強力な思考モデルを提供してくれるのだから、まことに残念な話である。

スイス・アーミーナイフをズボンのポケットに (または、小物入れに) 入れて、持ち歩いている人は多い。スイス・アーミーナイフは持っていると重宝な道具だ。それには、何本かのナイフ、ねじ回し、ピンセット、つまようじ、爪やすり、コルク抜き、他にもたぶん、いろいろ付いているだろう。日常のちょっとした雑用には、何にでも使える簡単な道具があれば済むのだから、そうした用途にはまさにピッタリの道具である。

しかしながら、熟練した大工は、スイス・アーミーナイフを使って家を建てたりしない。彼は、その代わりに道具箱を持っていて、そこには用途別の工具 --- のこぎり、金槌、ねじ回し、鉋など --- がぎっしり詰まっている。しかも、彼は一つ一つの工具について、適材適所を心得ている。ねじ回しの柄で釘を打ち込んだりすることは絶対にないのだ。

ベル研究所にいた Unix の開発者たちは、プロのプログラマやコンピュータ・サイエンスの専門家ばかりだった。その彼らが、こういうことに気づいたのだ。万能型のプログラムは、たった一つのプログラムを使えばよいので、ユーザには受けがよいかもしれない。だが、いざ実際に作ってみると、そうしたプログラムは、

 a. 書くのが難しく、

 b. 保守やデバッグが難しく、

 c. 新しい状況に合わせて機能を拡張するのが難しい。

むしろ彼らは、プログラムは用途別の工具であるべきだと痛感した。要するに、個々のプログラムは、「一つの仕事をきちんとやってのければよい」。それ以上でもそれ以下でもない。そういったプログラムは、設計するのも、コードを書くのも、修正するのも、ずっと簡単である --- たった一つのことしかしないからだ。

それだけではない。適切な仕組みを使って、プログラムを組み合わせると、全体が部分の総和以上になることにも、彼らは気づいた。ある用途専用のプログラムをいくつか組み合わせると、どのプログラムもそのために作られたのではない、ある特定の作業をやってのけることができる。それも、それ専用のプログラムを書かなければならない場合よりも、はるかに迅速に、かつ簡単にやってのけられるのだ。この記事の以下では、そうした使用法の (基本的な) 例をいくつか紹介する。(大事なことを一つ付記しておく。急がば回れだ。必要になるかもしれないソフトウェア工具があれば、まずそれを作ること。道具箱に適切な工具がまだない場合の話であるが。)

I/O リダイレクション
============

シェルの入出力リダイレクションについて、基本的なこと、とくに標準入力、標準出力、標準エラーがどういうものかを、読者はよく御存じだと思う。要するに、標準入力とは、データの入力元、すなわち、データがそこからやって来る場所のことだ。データの入力元が、ディスク上のファイルだろうと、キーボードだろうと、磁気テープだろうと、それどころかパンチカード・リーダーだろうと、プログラムはそれを知る必要もなければ、気にかける必要もない。同様に、標準出力とは、データの溜まる場所、データがそこに行く場所のことだ。プログラムとしては、それがどこになろうと、知らなくてもよく、気にかけなくてもよい。標準入力からデータを読み込み、それに対して何らかの処理を行い、標準出力に送り出すだけのプログラムを、水道のパイプラインのフィルターになぞらえて、「フィルター (filter)」と呼ぶ。

Unix のシェルでは、データのパイプラインを作るのはとてもやさしい。

     program_to_create_data | filter1 | ... | filterN > final.pretty.data

ここでは、まず最初に生のデータを作成している。各フィルターがそのデータに対して何らかの変形を次々に行い、最終的に、データが希望どおりの形になって、パイプラインから抜け出してくる。

標準入力と標準出力については、それでよい。では、標準エラーはどこで登場し、どんな役割を果たすのだろうか？上記パイプラインの filter1 について考えてほしい。データを読んでいるうちにエラーが起きたら、どうなるだろうか？ filter1 がエラーメッセージを標準出力に書き出したら、そのメッセージはパイプラインを下って filter2 の入力に飲み込まれてしまう。そうなると、ユーザはたぶんメッセージをまったく目にしないことになるだろう。そこで、プログラムとしては、ユーザがエラーメッセージに気がついてくれるように、それを送ることのできる場所が必要になる。それが、標準エラーなのであり、標準エラーは通常、現在使用しているコンソールやウィンドウに結びついている。プログラムの標準出力を使用中のスクリーン以外にリダイレクトしている場合でも、それは変わらない。

フィルター・プログラムが協力し合うためには、データのフォーマットについて互いに合意している必要がある。最も素直で使いやすいフォーマットと言えば、何と言っても、行分けされたテキストだ。そして、Unix のデータファイルは、たいていの場合、まさに、ASCII LF (Line Feed) 文字によって行分けされたバイトの連続なのである。なお、この LF 文字は、Unix の文書では「改行 (newline)」と呼ばれる習慣になっている (C のプログラマにとっては \n だ)。これこそ、すべての伝統的なフィルター・プログラムによって使用されて来たフォーマットである。 (昔のオペレーティング・システムの多くは、バイナリ・データを扱うための複雑な手段や専用のプログラムを備えていた。だが、Unix は、ただ単にテキストエディタでデータを見たり編集できたりする方がはるかに簡単だという考えから、そうした道具をずっと敬遠してきたのである。)

さて、前置きはこれくらいで十分だ。まず、道具のいくつかをざっと見てみよう。その後で、そうした道具をおもしろいやり方で組み合わせる方法をご覧に入れる。以下の解説では、当面の問題に関係のあるコマンドライン・オプションしか取り上げない。いつでもそうすべきことだが、コマンドについて詳しいことを知りたかったら、ご使用のシステムの文書を参照なさるとよい。

who コマンド
========

最初に取り上げるプログラムは、who コマンドだ。これは単独で使うと、現在ログインしているユーザのリストを生成する (参照: who invocation)。筆者がこの原稿を書いているのは、シングルユーザのシステムだが、数人のユーザがログインしていることにしよう。

     $ who
     -| arnold   console Jan 22 19:57
     -| miriam   ttyp0   Jan 23 14:19(:0.0)
     -| bill     ttyp1   Jan 21 09:32(:0.0)
     -| arnold   ttyp2   Jan 23 20:48(:0.0)

ここで $ はお馴染みのシェルプロンプトであり、筆者はそれに対して who と打ち込んだわけだ。三人のユーザがログインしており、筆者は二度ログインしている。伝統的な Unix のシステムでは、ユーザ名はアルファベット 8 文字までということになっている。このちょっとした豆知識が、後で役に立つことになる。 who の出力は悪くはない。だが、大しておもしろいデータでもない。

cut コマンド
========

次に注目するプログラムは cut コマンドだ。このコマンドは、入力されたデータから縦の列 (columns) やフィールドを切り出す (参照: cut invocation)。そこで、cut に命じて、/etc/passwd ファイルからログイン名とフルネームだけ表示させるといったことができる。 /etc/passwd には、七つのフィールドがあり、おのおのコロンで区切られている。

     arnold:xyzzy:2076:10:Arnold D. Robbins:/home/arnold:/bin/bash

1 番目と 5 番目のフィールドを取り出すには、次のように cut を使用する。

     $ cut -d: -f1,5 /etc/passwd
     -| root:Operator
     ...
     -| arnold:Arnold D. Robbins
     -| miriam:Miriam A. Robbins
     ...

-c オプションを付けると、 cut は入力行中の特定の文字 (すなわち、特定の縦の列) を切り出す。これは、入力データが固定幅のフィールドを持ち、フィールド・セパレータがないときに便利である。たとえば、今月の月曜日は、何日と何日かをリストするには、次のようにする。

     $ cal | cut -c 3-5
     -| Mo
     -|
     -|  6
     -| 13
     -| 20
     -| 27

sort コマンド
=========

次に sort コマンドを一瞥する。これは Unix 風のシステムにおける最も強力なコマンドの一つであり、パイプを使って手の込んだデータ処理を行うとき、気がつくと使っていることがよくあるものだ。

sort コマンドは、コマンドラインで指名された各ファイルを読み込んで、ソートする。その後で、ソートしたデータをマージし、それを標準出力に書き出す。コマンドラインでファイルが指定されていない場合は、標準入力を読み込む (こうして、フィルターになる)。ソートは、文字の照合順序、あるいは、ユーザが順序について指定した基準に基づいて行われる (参照: sort invocation)。

uniq コマンド
=========

最後に目を向けるのは (少なくとも今のところはだが)、uniq プログラムだ。データのソートをしていると、結果に重複行が現れることがよくある。内容が全く同じ行だ。たいていの場合、各行は一つだけあればよい。そこで、uniq の出番になる。uniq プログラムは、標準入力を読み込み、連続する同一行については、そのうちの一件だけを表示する。uniq には、オプションがいくつかある。後で -c オプションを使うことになるが、これはユニークな、つまり他と違っている各行を表示するとき、その行が入力中に現れた回数を前に付けるものである (参照: uniq invocation)。

工具 (tools) を組み合わせる
==================

さて、大規模な ISP のサーバーシステムがあって、何十人ものユーザがログインしているとしよう。経営側がシステム管理者に、ログインしているユーザのソートしたリストを生成するプログラムを書くことを求めている。しかも、あるユーザが多重ログインをしていても、その人の名前は出力に 1 回だけ現れればよいという条件がある。

システム管理者は腰を据えてシステムのマニュアル類に取り組み、そうした作業を実行する C のプログラムを書くこともできるだろう。そのためには、たぶん数百行のコードが必要であり、プログラムを書いて、テストして、デバッグするには、2 時間ぐらいかかるはずだ。それに対して、ソフトウェアの道具箱に精通しているシステム管理者なら、 C のプログラムを書く代わりに、ログインしているユーザのリストを生成するところから始めることができる。

     $ who | cut -c1-8
     -| arnold
     -| miriam
     -| bill
     -| arnold

次に、リストをソートする。

     $ who | cut -c1-8 | sort
     -| arnold
     -| arnold
     -| bill
     -| miriam

最後に、ソートしたリストを uniq に渡して、重複を除く。

     $ who | cut -c1-8 | sort | uniq
     -| arnold
     -| bill
     -| miriam

実を言うと、sort コマンドには -u というオプションがあって、uniq がやることをやってくれる。しかし、uniq にはほかの働きもあり、そちらは sort -u で代用することができない。

システム管理者が、以下のように、このパイプラインをシェルスクリプトにしておけば、システムのすべてのユーザが利用できるようになる (# はシステム管理者、すなわち root のプロンプトだ)。

     # cat > /usr/local/bin/listusers
     who | cut -c1-8 | sort | uniq
     ^D
     # chmod +x /usr/local/bin/listusers

ここには、心に留めておくべき重要なことが四つある。まず第一に、1 行のコマンドラインにたった四つのプログラムを書くことで、システム管理者は約 2 時間分の仕事をしないで済ますことができた。それだけではない。シェルのパイプラインは、 C のプログラムを使った場合と比べても、ほぼ同じくらい効率がよく、プログラマの労働時間という点から見ると、ずっとずっと効率がよい。人間の労働時間はコンピュータの時間よりはるかに高価であり、「何もかもやるには、いつだって時間が足りない」現代社会では、プログラマの時間を 2 時間も節約するのは、馬鹿にできない成果だ。

二番目に、ツールを組み合わせることで、個々のプログラムの作者が想像もしなかったような、ある特定の目的のための仕事をやってのけることができる。これも、強調しておくべき重要なことである。

第三に、ここでやって見せたように、段階を追ってパイプラインを構成するのも有益な方法だ。そうすれば、パイプラインの段階ごとにデータを目で見ることができるので、ツール類を間違いなく適切に使っているという自信を得ることができる。

最後に、実行したパイプラインをシェルスクリプトにまとめておけば、他のユーザがそのコマンドを使うことができる。彼らのために作成した手の込んだコマンドの配管工事を、彼らは憶える必要すらないのだ。どうやって実行するかという点から見ると、シェルスクリプトもコンパイルされたプログラムも見分けが付かないのである。

ここまでは準備運動だ。続いて、もっと複雑なパイプラインをもう二つご覧に入れよう。そのためには、工具をもう二つ紹介する必要がある。

一つ目は tr コマンドだ。``transliterate (翻字する、字を置き換える)'' の意味である。 tr コマンドは、一字一字処理して行くというやり方で、文字を置き換える (参照: tr invocation)。通常、このコマンドを使用するのは、大文字を小文字に変換するといったことのためである。

     $ echo ThIs ExAmPlE HaS MIXED case! | tr '[:upper:]' '[:lower:]'
     -| this example has mixed case!

役に立ちそうなオプションがいくつかある。

-c
     リストされた文字の補集合を動作対象にする。言い換えると、指定された集合に存在しない文字に対して操作が行われる。

-d
     一つ目の集合にある文字を出力から削除する。

-s
     出力中の連続する同一文字を、ただの 1 文字に圧縮する。

すぐ後で、この三つのオプションをすべて使うことになる。

紹介するもう一つのコマンドは、comm だ。 comm コマンドは、二つのソートされた入力ファイルを入力データとして受け取り、両ファイルの各行を三つの列に分けて表示する。出力される列は、一番目のファイルにのみ存在する行、二番目のファイルにのみ存在する行、両方のファイルに存在する行の順番である。-1, -2, -3 というコマンドライン・オプションを付けると、対応する列を表示しないようになる。 (これは直感的ではないので、ちょっとした慣れが必要だ。参照: comm invocation) 例を挙げよう。

     $ cat f1
     -| 11111
     -| 22222
     -| 33333
     -| 44444
     $ cat f2
     -| 00000
     -| 22222
     -| 33333
     -| 55555
     $ comm f1 f2
     -|         00000
     -| 11111
     -|                 22222
     -|                 33333
     -| 44444
     -|         55555

ファイル名を - にすると、comm は通常ファイルではなく、標準入力を読み込む。

これで、気の利いたパイプラインを組み立てる準備ができた。最初に作るアプリケーションは、単語の出現頻度カウンターである。これは、ある特定の単語を使いすぎていないかどうか、文書の作成者が判断するとき、役に立つ。

最初のステップは、入力ファイル中のすべての文字を大文字か小文字のどちらかに統一することである。 ``The'' と ``the'' は、頻度計算にとって同じ単語だ。

     $ tr '[:upper:]' '[:lower:]' < whats.gnu | ...

次のステップは、句読点を除去することだ。引用符の付いている単語と付いていない単語も同じものとして扱った方がよいだろう。それならば、句読点類をすっぱり取り除いてしまうのが、一番簡単だ。

     $ tr '[:upper:]' '[:lower:]' < whats.gnu | tr -cd '[:alnum:]_ \n' | ...

二番目の tr コマンドは、リストされた文字の補集合を操作対象にしている。すなわち、アルファベットのすべての文字、数字、アンダースコア、空白以外を対象にするわけだ。 \n は改行文字のことであり、これもそのまま残さなければならない。 (実用に供するスクリプトでは、ついでに ASCII タブ文字も残した方がよいだろう。)

この時点で、空白 (訳注: 改行を含む) で区切られた単語からなるデータができていることになる。単語には、英数字 (それにアンダースコア) しか含まれていない。次のステップは、データをバラして、1 行 1 単語になるようにすることだ。そうすれば、すぐ後で見るように、出現回数の計算がずっと楽になる。

     $ tr '[:upper:]' '[:lower:]' < whats.gnu | tr -cd '[:alnum:]_ \n' |
     > tr -s ' ' '\n' | ...

このコマンドは、空白を改行に変える。-s オプションが付いているので、出力中の連続する改行文字はたった 1 個に圧縮され、空行が取り除かれることになる。 (なお、2 行目行頭の > という記号は、シェルの二次プロンプトである。シェルがユーザに、コマンドがまだ最後まで打ち込まれていないと知らせるとき、これが表示される。)

今や、1 行 1 単語からなるデータが手元にある。句読点は含まれず、すべて小文字だ。これで、各単語の出現回数を数える準備が整った。

     $ tr '[:upper:]' '[:lower:]' < whats.gnu | tr -cd '[:alnum:]_ \n' |
     > tr -s ' ' '\n' | sort | uniq -c | ...

この時点で、データはたぶんこんなふうになっているだろう。

          60 a
           2 able
           6 about
           1 above
           2 accomplish
           1 acquire
           1 actually
           2 additional

なんと、出力が出現回数ではなく、単語によってソートされている！こちらとしては、最も頻繁に使われる単語ほど先に表示したいのにだ。幸いなことに、それは簡単に実現できる。sort のオプションをもう二つ使うだけでよい。

-n
     文字としてではなく、数値としてソートする。

-r
     逆順にソートする。

最終的なパイプラインは次のようになる。

     $ tr '[:upper:]' '[:lower:]' < whats.gnu | tr -cd '[:alnum:]_ \n' |
     > tr -s ' ' '\n' | sort | uniq -c | sort -n -r
     -|    156 the
     -|     60 a
     -|     58 to
     -|     51 of
     -|     51 and
     ...

ふう、憶えることがどっさり！ うん、でもね、同じ原則を応用してるだけなんだよ。たった 2 行、6 個のコマンドで (実際には、長い 1 行を便宜上 2 行に分割しているだけだが) 興味深く有用な作業をするプログラムが出来上がった。それも、同じこことする C のプログラムを書くよりもずっと短い時間でだ。

上記のパイプラインをちょっといじるだけで、なんと、簡単なスペルチェッカーが出来てしまう。ある単語の綴りが正しいかどうかを判断するには、辞書で調べさえすればよい。その単語が辞書になければ、綴りを間違えている可能性が高いわけだ。そこで、とりあえず、辞書が必要になる。辞書の在り処は、慣例からすると /usr/dict/words だ (現在では /usr/share/dict/words かもしれない)。筆者の GNU/Linux システムでは (この記事を 2000 年 11 月に改訂したとき使用したのは、Redhat Linux 6.1 である)、それはソートされた 45,402 語からなる辞書である。

それでは、自分の作ったファイルをどうやって辞書と比べるのか？前の例と同様、ソートした単語のリストを 1 行 1 語の形式で生成する。

     $ tr '[:upper:]' '[:lower:]' < whats.gnu | tr -cd '[:alnum:]_ \n' |
     > tr -s ' ' '\n' | sort -u | ...

必要なのは、辞書にない単語のリストだけだ。そこで、comm の出番になる。

     $ tr '[:upper:]' '[:lower:]' < whats.gnu | tr -cd '[:alnum:]_ \n' |
     > tr -s ' ' '\n' | sort -u |
     > comm -23 - /usr/dict/words

-2 と -3 のオプションを使うと、辞書 (2 番目のファイル) にしかない行と、両方のファイルにある行が排除される。1 番目のファイル (標準入力、すなわち、自分が使った単語のリストだ) にしかない行は、辞書に存在しない単語だ。そうした単語は、綴りを間違えている可能性がかなり高いわけである。ご覧に入れたこのパイプラインは、Unix における本格的なスペルチェッカーへの最初の一歩だったのである。

他にも一言述べておくべきツールがいくつかある。

grep
     ファイルを調べて、正規表現にマッチするテキストを検索する。

wc
     行数、単語数、文字数を計算する。

tee
     データが流れるパイプのための T 字管。データをファイルと標準出力にコピーする。

sed
     ストリーム・エディタ。上級ツール。

awk
     データ処理用の言語。これも上級ツール。

ソフトウェア工具論が取り入れたものに、次のちょっとしたアドバイスもある。「骨の折れる部分は、他の奴にやらせろ」。すなわち、ある道具を選んで、必要なことの大部分をやらせ、それから、その結果に手を加えて、こちらの望む形にする、ということである。

要約しておこう。

 1. 個々のプログラムは、一つの仕事をきちんとやってのければよい。それ以上でもそれ以下でもない。

 2. プログラムを適切な配管工事で組み合わせると、全体が部分の総和以上になる結果が生じる。作者が想像もしなかったようなプログラムの新しい使用法が見つかることもある。

 3. プログラムは決して余計なヘッダや追加情報を出力すべきではない。そうしたものもパイプラインの先へ送られてしまうかもしれないからだ。 (これは、これまでに言及しなかったが、重要なことだ。)

 4. 骨の折れる部分は、他の奴にやらせろ。

 5. 自分の道具箱をよく知れ！ 個々のプログラムを適切に使え。適切なツールがなかったら、それを作れ。

これを執筆している時点で、ここで取り上げたプログラムはすべて次の URL から手に入れることができる。

http://ftp.gnu.org/old-gnu/textutils/textutils-1.22.tar.gz

もっと新しいバージョンは以下の場所にある。

http://ftp.gnu.org/gnu/coreutils

この記事で筆者が述べたことに、新しいことは何もない。ソフトウェアは工具だという思想が最初に紹介されたのは、Brian Kernighan と P.J. Plauger による Software Tools という本の中だった (Addison-Wesley, ISBN 0-201-03669-X)。ソフトウェア工具の書き方と使い方を教えるこの本は、1976 年に執筆され、ratfor (RATional FORtran) という名前の FORTRAN のプリプロセッサを使用している。その当時、C は今ほどありふれてはいず、FORTRAN がそうだったのだ。最後の章では、ratfor を FORTRAN に変換するプロセッサを ratfor で書いて見せている。ratfor は C にとてもよく似ているので、 C を御存じの方なら、コードを追うのに何の苦労もないことだろう。 (訳注: Software Tools の翻訳は「ソフトウェア作法」という題で 1981 年に出版されている。木村泉 訳、共立出版)

1981 年に本は改訂され、Software Tools in Pascal という形でも手に入るようになった (Addison-Wesley, ISBN 0-201-10342-7)。どちらの本も現在でも入手可能であり、プログラマなら、一読の価値が十分にある。この 2 冊の本が筆者のプログラミングに対する見方を大きく変えてくれたことに、疑いの余地はない。

両方の本にあるプログラムは、Brian Kernighan のホームページから手に入れることができる (http://cm.bell-labs.com/who/bwk)。Software Tools Users Group という活動的なグループが長年に渡って存在し、そのメンバーがオリジナルの ratfor プログラムを、FORTRAN コンパイラを持っているほとんどすべてのコンピュータ・システムに移植していた。だが、1980 年代の中頃に Unix が大学を越えて浸透し出すにつれて、グループの人気は衰えて行った。

現在では GNU のコードをはじめ、Unix クローンのプログラムがどんどん作られており、上記のプログラムはほとんど関心を持たれていない。それに、現代の C のバージョンの方がはるかに効率がよく、できることも上記のプログラムよりずっと多くなっている。それでも、よいプログラミング・スタイルのお手本として、また、今でも価値がある考え方を熱心に説いている点において、この 2 冊の本は肩を並べるものがない。筆者としては、大いにお薦めする次第だ。

謝辞: ソフトウェア工具の最初の道具鍛冶である、Bell 研究所の Brian Kernighan 氏に、この記事を読んでチェックしてくださったことについて、心からお礼を申し上げる。

翻訳について
******

この文書は GNU core utilities version VERSION の info マニュアルの翻訳である。間違いの御指摘や改良の御提案は Linux JM project 宛にメールでなさっていただきたい (linuxjm-discuss@lists.osdn.me)。

まず最初に、coreutils の日本語版 info マニュアルの呼び出し方を簡単に説明する。 coreutils の 日本語版 info が install-info コマンドを使ってきちんとシステムにインストールされているならば、コマンドラインから info coreutils-ja で日本語マニュアル全体を、info chmod-ja などで個々のプログラムの日本語マニュアルを呼び出すことができる。英語版を読むときは、今までどおり info coreutils や info chmod とすればよい。個々のコマンドについては、英語版なら info coreutils 'cp invocation'、日本語版なら info coreutils-ja 'cp invocation' といったマニュアルの呼び出し方もある。

また、info を引数なしで実行すると、 info マニュアルのトップレベルのメニューが開く。ここで、メニュー項目にカーソルを合わせて、リターンキーを押せば、その項目に飛ぶ。しかし、読みたい項目をキー操作で指定する方が簡単である。たとえば、 m キーを押した後 chmod-ja と打ち込んで、リターンキーを押せば、chmod コマンドの日本語版マニュアルが、 chmod だけなら英語版マニュアルが表示される。

coreutils-ja、chmod-ja などと -ja を付けるのは、info プログラムを起動するときと、 info のトップレベル・メニューにいるときだけである。すでに日本語版 coreutils マニュアルのどれかを (それが coreutils-ja であれ、dd-ja であれ) info コマンドで開いている場合は、 -ja を後ろに付ける必要がなくなる。と言うより、付けてはいけない。 coreutils-ja の先頭ページのようにコマンドのメニューが存在するページでは (実際には、スクロールしないと、メニューが見えないが)、たとえば、 m に続けて chmod と打ち込み、リターンキーを押すだけで、 chmod の日本語の説明が開く。また、日本語 coreutils マニュアルの任意のページから coreutils-ja の他のノードへ直接飛ぶ場合も (ノードは、ほぼ章や節に相当する)、 g キーを押してから、chmod invocation などとノード名を打ち込み、リターンキーを押せばよい。m, g、どちらの場合も、タブで文字列の補完ができる。

info マニュアルの読み方の基本は、「メニューやクロスリファレンスにカーソルを合わせてリターンキーを押せば、その項目に飛ぶ。スペースで先に進み、バックスペースで後戻りする。l キーで直前に開いていたノードに戻る。 q キーで終了する」である。たぶん coreutils-ja.info のパッケージには、README.ja というファイルが含まれていると思う。 info マニュアルの呼び出し方や使用法について、そこにもう少し詳しい説明を書いておいたので、ご覧になっていただきたい。

ここで、日本語の info マニュアルを使用するときの問題点を挙げておく。

 1. info コマンドのバージョンによっては、行末の処理が上手ではない。そのため、行末に余計な文字が入ることがある。そうしたときは、C-l を押して (Ctrl と l (エル) キーを同時に押す)、画面の再描画を行っていただきたい。表示が正常になるはずである。 Emacs の info リーダーでは、この問題はめったに起きない。

 2. 最近の info コマンド (たとえば、バージョン 6.3) では、s や / による日本語の単語の検索ができるようになった。 C-s による日本語のインクリメンタル検索も可能になっている。バージョンの古い info では、英単語による検索はできても、日本語の単語による検索はできないので、注意していただきたい。

 3. X の端末エミュレータで info コマンドを使用する場合、端末エミュレータとフォントの組み合わせによっては、文字列を囲むクォートの表示がおかしくなることがある。フォントに「Monospace Regular」を使っているなら、「VL Pゴシック regular」か「Liberation Mono Regular」に変えてみるとよいかもしれない (それはそれで、別の問題が出る可能性もあるが)。ちょっと古風だが、日本語が使える xterm (uxterm など) なら、クォートの表示にまず問題はない。

 4. coreutils の info のこの翻訳では、インデックスの日本語化まで手が回らなかった。そのため、インデックスは英語のままである。

 5. 古めの Emacs でこの翻訳を読もうとすると、文字化けするかもしれない。回避法があるのかもしれないが、訳者にはわからなかった。

この翻訳の最初の版は、coreutils-8.20 所収の texinfo ファイルを元に、 Linux JM project のために訳者が新たに翻訳したものだった。以下に、そのときの後書きをほぼそのまま載せておく。

この info マニュアルの原文は、本文の「序」でも述べているように、各プログラムの man ページを統合し、増補・改訂したものである。この info マニュアルがまとめられるにともない、公式の man ページの方は、コマンドの --help オプションで見ることができるものとほぼ同文の、簡単な内容のものになった。

従来どおりの詳しい man ページを希望する人たちも存在した。そのために作られたのが、gnumaniak の man ページであり、従来の man ページを info の情報で増補したものだったが、現在では保守されていないようだ。

作成の経緯がそうしたものなので、この info マニュアルの原文には、 gnumaniak の man ページの原文とほとんど内容が同じものがある。翻訳作業に当たっては、すべての項目について gnumaniak の man ページの翻訳を参考にした。あちらの訳文の方がよくできている項目もある (gnumaniak の翻訳は http://linuxjm.osdn.jp/html/gnumaniak/man1/ にある)。

この翻訳は、Linux JM project の gnumaniak の翻訳に多くを負っている。そこで、まず、gnumaniak の翻訳者の方々 --- 中野武雄、佐藤裕一、白方健太郎、 Kazuyuki Tanisako、Omo Kazuki の諸氏にお礼を申し上げる。

訳文を見直す際には、西尾太さんが以前翻訳なさった coreutils-5.2.1 の info を参考にした。また、当然ながら、新しい man ページ (こちらの翻訳者は、たぶん Yasuaki Taniguchi さんと Akihiro MOTOKI さん) とも、できるだけ突き合わせた。西尾さん、Taniguchi さん、元木さんにもお礼を申し上げる。

gnumaniak や coreutils の man や info の翻訳をなさった方で、私がお名前を挙げ忘れた方がいらっしゃるかもしれない。お知らせくだされば、追加訂正する。

訳文には間違った箇所がたくさんあると思う。そのへんは、ご寛恕いただきたい。皆さんがこの訳文を叩き台にして、増補・改訂・改訳を続け、より新しく、よりわかりやすい、そして、より正確な coreutils の翻訳を作ってくだされば、最初の翻訳者としてそれにまさる喜びはない。

2017-03-26 訳者

[翻訳履歴]

  * 2014-03-15

     coreutils-8.20 を翻訳    by 長南洋一

     ptx, tsort, chcon, runcon は未訳

  * 2014-11-25

     coreutils-8.22 を元に増補・改訂    by 長南洋一

     numfmt, ptx, tsort, chcon, runcon を翻訳

  * 2016-07-07

     numfmt の章の構成を修正。訳文の訂正と細かい変更    by 長南洋一

  * 2017-03-26

     coreutils-8.26 を元に増補・改訂    by 長南洋一

  * 2019-09-09

     訳文の訂正と変更    by 長南洋一

GNU Free Documentation License
******************************

     [file fdl.texi not included]