【permission denied】ファイル書き込みできない原因あるある

2019年9月20日Linux, PHPLinux, PHP, テクニック

結論

「permission denied」が出ていて、ファイル書き込みができないときに見るべきポイントは以下です。

  • 書き込み対象ファイルの書き込み権限
  • 書き込み対象ファイルの親ディレクトリの書き込み権限+実行権限
  • シンボリックリンクではなく、真のファイルを見ること
  • SELinuxの設定


「permission denied」でファイルに書き込めない主な原因

エラーメッセージの通り、権限設定によって書き込めないことがほとんどの原因です。


ファイル書き込みできないときの権限系の原因

書き込み対象ファイルの書き込み権限

最もポピュラーで最もありがちな原因は書き込み対象ファイルに書き込み権限がないことです。

書き込みをしようとしているユーザーに適切な権限があるのかを確かめましょう。
例えばapacheでPHPを実行してロギングしようとしている場合は、実行ユーザーは「apache」や「httpd」のようなユーザーです。

# 実行ユーザーがapacheの時、以下のtarget.logに書き込むためには書き込み権限が必要
$ ls -l 
-rwxrwx--- 1 user1  user1  3755 Sep 10 22:16 target.log
$ chmod 777 target.log
$ ls -l 
-rwxrwxrwx 1 user1  user1  3755 Sep 10 22:16 target.log


書き込み対象ファイルの親ディレクトリの書き込み権限+実行権限

意外と見落としがちなのが、書き込み対象ファイルの親ディレクトリに書き込み権限と実行権限が付いていないことです。

親ディレクトリには書き込み権限はつけていても、実行権限はつけていないことがよくあります。

# 対象ファイルとその親ディレクトリに書き込み権限があっても、親ディレクトリに実行権限がついていないと書き込みができない。
# 下記は実行ユーザーがuser1の場合
$ tree parent_dir
parent_dir
`-- target.log
0 directories, 1 file
$ ls -l 
drwxrwxrw- 1 user2  user2  704 Sep 10 23:01 parent_dir
$ ls -l parent_dir
-rwxrwxrwx 1 user1  user1  3755 Sep 10 22:16 target.log
# 対象ファイルの親ディレクトリに書き込み権限+実行権限をつければ書き込みできる
$ chmod 777 parent_dir
$ ls -l 
drwxrwxrwx 1 user2  user2  704 Sep 10 23:01 parent_dir

親ディレクトリの権限に関しては以下の記事が詳しいです。
実行権限のみ欠けたディレクトリ(rw-)の挙動 – Qiita


シンボリックリンクではなく、真のファイルを見ること

稀にしかないケースにはなりますが、権限をつけたのが実は本当の対象ファイルではなくシンボリックリンクである可能性があります。
以下のように「ls -l」でシンボリックリンクの情報が分かるので見逃さないようにしましょう。

$ ls -l
lrwxr-xr-x  1 user1  user1     9 Sep 19 23:01 target.log -> /tmp/true_target.log


ファイル書き込みできないときのセキュリティ関連の原因

SELinuxの設定

CentOSを利用している場合、SELinuxが悪さをしているケースもあるようです。こちらに関しては以下の記事が参考になりそうです。

CentOS7,Apache2でディレクトリへのデータ書き込みができない – Qiita


まとめ

基本的には権限の設定が間違っていることがほとんどです。まずはそこを整理しましょう。

サイト運営者 えぬたけ


都内で働くゆるふわフルスタックwebエンジニア。