読み取り専用ディレクトリのファイルを変更できますか? [コピー]

読み取り専用ディレクトリのファイルを変更できますか? [コピー]

私は読んだ:ファイルを適切に変更する方法はありますか? 一時ファイルを生成しない命令を使ってその場でファイルを修正する方法があるかどうか疑問に思います。ディレクトリを作成 mkdir read_only し、read_onlyにいくつかのファイルを作成するとします。ファイルの作成が正常に完了したら、を実行しますchmod 555 read_only。これで、一時ファイルを使用せずにファイルを変更できますか?特に、私はbashスクリプトを介して実行できるソリューションが欲しいです。これが可能かどうかは知りたくありません。また、解決策を探しています。これまでbash / unixコマンド管理を使用して得られたすべてのアイデアは、一時ファイルを生成します。

編集:私の質問は重複していないようです。「書き込み」権限を持つファイルを編集できますが、親ディレクトリは編集できませんか?次の理由で:

  • 私は単に「はい」と尋ねる以上の解決策を探しています。そして彼らが尋ねるのは「はい」だけでした。
  • おそらく、重複した回答が私の質問に完全に答えていない可能性があります。 Bashスクリプトに入れることができるコマンドを要求します。

ベストアンサー1

ディレクトリ内のファイルを作成または削除するには、ディレクトリへの書き込み権限が必要ですが、ディレクトリ内のファイルに書き込むことはできません。ほとんどのシェルコマンドは、出力ファイルが提供されると、単に書き込みのためにファイルを開き、ファイルの古いデータを置き換えます。リダイレクト>演算子は既存のファイルを切り捨て(つまり、既存のファイルの内容を削除してファイルの長さがゼロ)、書き込みを開始します。リダイレクト>>演算子を使用すると、データがファイルの末尾に追加されます。

ファイルの書き込みは、低レベルのインターフェイスによって提供される可能性によって制限されます。ファイルのバイトを所定の位置に上書きし、ファイルの末尾に追加し、ファイルを選択した長さに切り捨てることができます。次のバイトを前に移動している間(たとえば→ foobarfooNEWSTUFFbar、バイトを挿入したり、後続のバイトを前に移動している間(たとえば→ foobarfor、バイトを削除することはできません。ただし、移動したいデータを読み取って新しい場所に書き込んでこれらの操作をシミュレートする場合は除外されます。

ファイルを適切に編集するときの問題は、問題が発生した場合(プログラムエラー、ディスクいっぱい、停電など)、ファイルの内容の一貫性を維持するのが難しいことです。そのため、強力なファイル処理には、新しいデータで一時ファイルを作成し、その一時ファイルを所定の場所に移動することが含まれることがよくあります。

ファイル編集のもう一つの制限は、読み書きに関連する複雑な操作がアトミックではないということです。これは、ファイルの変更中に他のジョブからファイルを読み取ろうとする場合にのみ問題になります。たとえば、最後の3バイトを読み取り()、新しいデータを書き込み(→)、最後に前の尾を追加(→)してに変更すると、同時foobarリーダーはファイルの状態の他の部分も表示できます。部分的に作成されたデータのみを含みます。 。繰り返しますが、一時ファイルを所定の位置に移動することはアトミックな操作であるため、最初に一時ファイルに書き込むとこの問題は解決されます。fooNEWSTUFFbarbarfoofooNEWSTUFFfooNEWSTUFFfooNEWSTUFFbarfooNEWSTUFF

これらの制限を気にしない場合は、その場所でファイルを変更できます。データを追加するのは簡単です(>>)。他のほとんどの変換はより複雑です。一般的な落とし穴は

somefilter <somefile >somefile

ファイルの内容に適用できませんsomefilter:演算子は>読み取りを開始する前に出力ファイルを切り捨てます。somefilter

Joey Hessのmoreutilsというファイルが含まれています。spongeこれで問題が解決しました。出力をにリダイレクトするのではなく、にパイプしてすべてのsomefile入力spongeを読み取るそれから読み取り入力で既存のファイルを上書きします。フィルタが失敗しても、まだ部分的なデータを取得できます。

somefilter <somefile | sponge somefile

ない場合、spongeこの問題を解決するための移植可能で簡単な方法は、最初にデータをメモリに読み込むことです。

content=$(cat somefile; echo a)
content=${content%a}

このecho aビットは、ファイルの終わりの改行を維持するために使用されます。コマンド置換は常に末尾の改行を削除します。その後、コンテンツをコマンドに渡すことができます。

printf %s "$content" | somefilter >somefile

これにより、ファイルの内容がフィルタ出力に置き換えられます。何らかの理由でコマンドが失敗すると、ファイルの元の内容は失われ、ファイルには失敗する前にコマンドで書き込まれたすべてのデータが含まれます。

ほとんどのシェルはヌルバイトをサポートしていないため、この方法はバイナリファイルでは機能しません。

ファイルを修正するもう1つの方法は、次を使用することです。edsedと非常によく似たエディタですsedが、sedの1行ずつ作業するのではなく、ファイルをメモリにロードしてその場所に保存します。

ファイルをメモリにロードしたり一時ファイルを作成したりすることなく、標準のシェルツールを使用してファイルを操作するのは難しいですが、可能です。シェルリダイレクトとほとんどのテキスト処理ユーティリティは、ファイルに追加するか、最初から上書きすることを許可します。これにより、dd conv=notrunc seek=…見つからない部分に影響を与えずにファイルのオフセット内のデータを上書きできます。ファイルを適切に変更する方法はありますか?例えば。

おすすめ記事