web-dev-qa-db-ja.com

Linuxで「>>」を使用すると、bashはO_APPENDでファイルを開きますか?

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 >>は不明なので、ここで質問します。

38
Prem

私はこれを実行しました:strace -o spork.out bash -c "echo 1234 >> some-file"質問を理解してください。これは私が見つけたものです:

open("some-file", O_WRONLY|O_CREAT|O_APPEND, 0666) = 3

echoコマンドを実行したディレクトリに「some-file」という名前のファイルが存在しませんでした。

61
Bruce Ediger

これはBashで行われるだけでなく、標準で必要とされています。

Single Unix Specificationから

追加された出力リダイレクションは、Wordの展開から名前が付けられたファイルを、指定されたファイル記述子での出力用に開きます。ファイルは、POSIX.1-2008のシステムインターフェイスボリュームで定義されているopen()関数がO_APPENDフラグで呼び出されたかのように開かれます。ファイルが存在しない場合は、作成されます。

したがって、POSIX準拠のシェルはそれを行う必要があります。一部のUnixシステムでは、/bin/shは非POSIX Bourneシェルである可能性があり(BourneシェルはO_APPENDが発明される前に最初に作成されました)、使用可能なPOSIXシェルは通常kshです。これは、Solarisの/usr/xpg4/binなどの別のパスの場所でshとして使用できます。

51
Random832

ソースを見ると、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;
32
Eric Renouf

ローカル(非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
_

他のシェル、つまりdashdashsh of busybox 'とmkshは同じように動作します。

オプション_-e open_は、open()システムコールのみをトレースする_-e trace=open_を意味します。

19
Franklin Piat