(1/2)>や>>、>&といったひんぱんに使われるリダイレクトに対し、ほとんど使われることのないリダイレクトが>|と<>だ。実際には興味深い機能である、これら「知られざる」リダイレクトについて説明しよう。});あなたの知らないリダイレクト、>|と<>シェルが提供する機能はカーネルが提供している機能をダイレクトに利用するものが多い。シェルの記述がダイレクトにシステムコールに結び付くような機能が多いということだ。コマンドの実行、パイプ、リダイレクトなどは、そっくりそのままシステムコールに置き換わる。リダイレクトであれば、ほとんどのケースで>ないしは>>で事足りるはずだ。2>&1という記述はこれで1つの機能に思えるが、これは>&というリダイレクトの典型的な使い方の1つであり、つまりはリダイレクトだ。>、>>、>&はよく使われるリダイレクトといえる。sh(1)のマニュアルには次のように、9つのリダイレクトが紹介されている。>|この中でも特になじみのないリダイレクトが>|と≪≫だろう。実際、これらのリダイレクトが使われることはほとんどない。実はこれらは興味深い機能であり、シェルを極めていくのであれば、ぜひ使い方を知っておきたい。今回はsh(1)のソースコードを読みながら、これらリダイレクトが何をするものかを紹介する。sh(ash)が適度なソースコード量で扱いやすい。リダイレクトの処理は/usr/src/bin/sh/redir.cに記載されている。-Cオプションを処理するため、また>|と処理コードを共有するために若干読みにくくなっているが、最終的にはopen(2)システムコールに置き換わっていることが分かる。movefd;caseで指定されている値は、パーサを通して分解されたパーツを示している。/usr/src/bin/sh/nodetypesにまとまった説明があるので見ておきたい。NTO:は>、NCLOBBERは>|だ。>>にはNAPPENDが割り当てられており、<>はNFROMTOが割り当てられている。fnameNTO:の処理は、-Cが指定されている場合に、次のようにファイルをオープンする処理になっている。-Cは、「既存のファイルが存在する場合には>での上書きは実施しない」というオプションだ。0)次のように-Cを指定してsh(1)を実行すると動きが分かる。-Cが指定されている場合、>でファイルを新規作成することはできるが、ファイルが存在する場合には上書きできない。>|は、たとえ-Cが指定されている場合でも、既存のファイルへの上書きを実施するためのリダイレクトだ。-Cが指定されている場合には処理が異なるが、-Cが指定されていない場合には>と>|は同じ処理をすることになる。NCLOBBER:の処理に移っているのはこのためだ。>と>|で処理を共有している。0666」のオプションでファイルを開くという処理をしていることになる。ファイルは書き込み専用で開き、ファイルが存在しない場合には0666にマスクを適用したパーミッションで新規作成し、開くと同時にトランケートを実施し、ファイルサイズを0にしてから書き込みを開始する、ということになる。ファイルを開いたあとは、movefd:へ処理を移している。break;開いたファイルが出力先、または読み込み元になるようにdup2(2)でコピーしていることが分かる。close(f);このように、実際にシェルのソースコードを読むことで、実際にはどのような動きをするものかがよく分かる。メールマガジンをご購読ください。申し込みページへITmediaはアイティメディア株式会社の登録商標です。