ファイルへの書き込みアクセスを非侵襲的にテストする方法は?


20

シェルスクリプトで、実際にファイルを変更せずに、ファイルへの書き込みアクセスを簡単かつ非侵襲的にテストするにはどうすればよいですか?

の出力を解析することはできましたがstat、実装と時間によって統計出力がどれだけ異なるかはわかりませんが、それは本当に複雑で、おそらく壊れやすいようです。

ファイルの最後に追加して、それが成功するかどうかを確認することもできますが、考えられる2つの理由から、潜在的に危険です。

  1. ここで追加を削除する必要があり、他のプロセスがファイルに書き込む場合、私の行が最後ではないため、これはすぐに重要になります。
  2. ファイルを読み取るプロセスには、そのファイルの内容に関する任意の要件がある場合があり、そのアプリケーションが壊れている可能性があります。

回答:


29

ユーティリティの- wフラグを使用するだけtestです:

[ -w /path/to/file ] && echo "writeable" || echo "write permission denied"

後でファイルに書き込む場合は、まだ書き込みできない可能性があることに注意してください。ファイルが移動した、許可が変更された、などの可能性があります。-w書き込み許可検出することもありますが、ファイルを書き込み不可にするために他の要因が介入します


1
もちろん!テストのマニュアルページをチェックすることを考えるべきだった。ありがとうございました。
user50849 14年

1
それはシェルの組み込みである@qweilunていますが、経由でmanページを表示することができますman testman [
混乱

5
@chaosこれはシェル組み込みおよび外部実行可能ファイルの両方である-試みtype -a
フォルカー・シーゲル

1
testeuidaccess単に許可ビットをチェックするソース使用ごと。書き込みアクセスを禁止する可能性のある他の要因(SELinuxなど)はありませんか?
ザムナッツ14年

2
@BroSlow、&&および||同等の優先順位を持ちます。それらは左から右に評価されます。
ワイルドカード

11

別のアプローチ:

if >> /path/to/file
then
    echo "writeable"
else
    echo "write permission denied"
fi

これは、追加のためにファイルを開こうとし、それが成功した場合、 コマンドを実行しません(つまり、nullコマンドを実行します)、ファイルへの出力で)。 

空のファイルが存在しない場合は作成されることに注意してください。

コマンドの-wオペレーターはtest単にa stat を実行してから、アクセスする必要があるように見えるかどうかを把握しようとします。私の代替手段(上記)はtest、アクセスチェックをシェルではなくカーネルによって強制するため、いくつかの特別な条件でのアプローチよりも信頼性が高くなります。例えば、

  • ファイルが非UNIXファイルシステム上にある場合-特に非Unixファイルサーバーからリモートでマウントされている場合- stat誤解を招くモード値を返す可能性があるため。
  • ファイルが読み取り専用でマウントされているファイルシステムにある場合。
  • ファイルにACLがあり、モードによってアクセス権があるように見えるが、ACLがそれを拒否する場合、またはその逆の場合。
  • セキュリティフレームワーク(AppArmor、SELinuxなど)がファイルへのアクセスを拒否する場合。

3
これをテストしました(Debianで)。どちらの時間も変更されておらず、それがどのUnixでも動作するはずの方法です。アクセス時間はファイルから読み取る場合にのみ更新する必要があり、変更時間はファイルに書き込む場合にのみ更新する必要があります。このコードはどちらもしません。@Schwern:あなたの声明の参照はありますか?試したことはありますか?
G-Manが「Reinstate Monica」と言う14

2
PS @muru:自分touchが所有しているが書き込みアクセス権のないファイルを試したところ、成功しました。私はそれchmodがファイルだと思いますchmod。したがってtouch、質問への回答としては絶対に役に立たないようです。
G-Manが「Reinstate Monica」と言う14

2
@ G-Manああ、それは面白い。IIRCにvimは、読み取り専用ファイルへの書き込みを強制されると、アクセス許可をすばやく変更するという動作があります。私はチェックしstracetouch「sがopenで失敗しEACCESたが、以降の呼び出しはutimensat、私が考える理由である、成功touchに成功全体終了に。
ムル14年

2
@muru:それをチェックしてくれてありがとう。utimensat(2)アクセス許可の要件: 1.書き込みアクセス(または)2.呼び出し元の有効なユーザーIDはファイルの所有者と一致する必要があります...」
Gマンは「モニカを元に戻す」と14年

3
シャンピニャックのような他の問題:>> file移植性がない(たとえば、zshでNULLCMDを実行する)ので、true >> file代わりに使用します。また、ファイルが名前付きパイプである場合、厄介な副作用があります。
ステファンシャゼル

3

G-manは正しい。常に真実を語る[ -w ]わけではない。ここに存在しないファイルとシェルからの許可拒否メッセージに対処するため:

( [ -e /path/to/file ] && >> /path/to/file ) 2> /dev/null && 
  echo writable || 
  echo not writable

更新:恐ろしいですね。まあ、そうです。うーん...それをどのように表現するか...これを使用しないでください。ステファンのコメントを参照してください。

結論は何ですか?[ -w ]本当のことを言わなくても、それは仕事をすること目的とする1つのコマンドです。そうでなければ、私たちはそれを非難し、バグレポートを書きます、そしてそれは将来機能します。動作し、使用する条件をよりよく確認してください[ -w ]。特別な場合のために特別なコードを書きます。回避策には独自の条件があります。

[ -w /path/to/file ]

先験的に最高です。


3
ファイルが名前付きパイプである場合、読み取りがない場合はハングし、リーダーがある場合でも厄介な副作用が発生します。test -wほとんどの実装ではaccess(2)、アクセス許可をテストするのに十分なはずです。
ステファンシャゼル
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.