echo 1234 >> some-file
を使用すると、ドキュメントには出力が追加されると記載されています。
私の推測では、some-fileが存在しない場合、O_CREATは新しいファイルを作成します。 >
が使用された場合、O_TRUNCは既存のファイルを切り捨てます。
>>
の場合:ファイルはO_WRONLY(またはO_RDWR)として開かれ、O_APPENDをシミュレートして終了操作が行われ、書き込み操作が行われますか?または、ファイルがO_APPENDとして開かれ、追加が行われることを確認するためにカーネルに残されますか?
出力ファイルがNFSマウントポイントからのものである場合、エコーによって挿入された一部のマーカーがconserverプロセスによって上書きされ、NFSのドキュメントにO_APPENDがサーバーでサポートされていないため、クライアントカーネルがそれを処理する必要があるため、これを尋ねています。 conserverプロセスはO_APPENDを使用していると思いますが、Linuxでのbash >>
は不明なので、ここで質問します。
私はこれを実行しました:strace -o spork.out bash -c "echo 1234 >> some-file"
質問を理解してください。これは私が見つけたものです:
open("some-file", O_WRONLY|O_CREAT|O_APPEND, 0666) = 3
echo
コマンドを実行したディレクトリに「some-file」という名前のファイルが存在しませんでした。
これはBashで行われるだけでなく、標準で必要とされています。
追加された出力リダイレクションは、Wordの展開から名前が付けられたファイルを、指定されたファイル記述子での出力用に開きます。ファイルは、POSIX.1-2008のシステムインターフェイスボリュームで定義されているopen()関数がO_APPENDフラグで呼び出されたかのように開かれます。ファイルが存在しない場合は、作成されます。
したがって、POSIX準拠のシェルはそれを行う必要があります。一部のUnixシステムでは、/bin/sh
は非POSIX Bourneシェルである可能性があり(BourneシェルはO_APPEND
が発明される前に最初に作成されました)、使用可能なPOSIXシェルは通常ksh
です。これは、Solarisの/usr/xpg4/bin
などの別のパスの場所でsh
として使用できます。
ソースを見ると、O_APPENDを使用しています。 make_cmd.c
のbash 4.3.30の場合、710-713行目は次のようになります。
case r_appending_to: /* >>foo */
case r_append_err_and_out: /* &>> filename */
temp->flags = O_APPEND | O_WRONLY | O_CREAT;
break;
ローカル(非NFS)ファイルシステムでstrace
を使用することを調べてみましょう:
_$ strace -eopen -- bash -c "echo foo >> /tmp/testfile000" 2>&1 | grep /tmp/testfile000
open("/tmp/testfile000", O_WRONLY|O_CREAT|O_APPEND, 0666) = 3
$ strace -eopen -- bash -c "echo foo > /tmp/testfile000" 2>&1 | grep /tmp/testfile000
open("/tmp/testfile000", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 3
_
他のシェル、つまりdash
、dash
、sh
of busybox 'とmksh
は同じように動作します。
オプション_-e open
_は、open()
システムコールのみをトレースする_-e trace=open
_を意味します。