【Linux】パーミッション・権限の入門&完全解説
この記事では中堅以上のエンジニアでも苦手意識を持つことが多いパーミッション・権限について分かりやすく解説します。
はじめに・パーミッションが分かりにくい理由
冒頭で述べたようにパーミッションに対して苦手意識を持っているエンジニアはたくさんいます。なぜなのでしょうか?
それは「パーミッションは複数の要素が組み合わさって確定する」という性質があるからです。
一つこのことを理解してもらうためにクイズを出します。
パーミッションには読み取り・書き取り・実行の3つが存在します。そこで例えばファイルAがあるとして、ファイルAに読み取り権限が付与されているとしたら、このファイルAの中身をcatコマンドで見ることはできるでしょうか?
・・・
答えは"必ずしもできるとは限らない"になります。
というのも先ほどのクイズの問いでは、ファイル読み取りをできるか否かを確定させるための要素がいくつか抜けてしまっているからです。抜けている要素は以下です。
- 誰に読み取り権限が与えられているのか
- ファイルAが存在するフォルダのパーミッションはどのように設定されているのか
- ファイルAが存在するフォルダの親フォルダのパーミッションはどのように設定されているのか
このようにパーミッション・権限と一言でまとめられても、実はフォルダのパーミッション、ファイルのパーミッション、それぞれのパーミッションが誰に与えられているのか、という複数の要素が関係してきてしまうのです。
この記事では複数の要素を理解した上で適切に権限設定できる状態になるために以下の順番で詳細に解説します。
- パーミッションの対象ユーザー
- ファイルの各パーミッションの意味(どんな操作の許可が与えられるか)
- フォルダの各パーミッションの意味(どんな操作の許可が与えられるか)
パーミッションの対象ユーザー
ここからは実際にコマンドの実行結果も確認しながら説明します。
ちなみに利用している環境はubuntuです。ただ利用しているコマンドが一般的なLinuxのコマンドなので、どんなLinuxOSを利用している方でも参考になると思います。ユーザーはringoという一般ユーザーを利用します。
パーミッションの付与対象ユーザーの確認には"ls -l"コマンドが利用できます。
ringo@computer:~$ touch test_file.txt # ファイル作成
ringo@computer:~$ mkdir test_dir # フォルダ作成
ringo@computer:~$ ls -l
total 4
drwxrwxr-x 2 ringo ringo 4096 Aug 9 01:19 test_dir
-rw-rw-r-- 1 ringo ringo 0 Aug 9 01:19 test_file.txt
“ls -l"を実行すると今いるフォルダ(カレントフォルダ)直下のファイルやフォルダを一覧で確認できます。
今回の場合、"ls -l"を実行する直前にファイルとフォルダを作成しているので、それらが表示されています。
test_dirの行を抜き出して区切り方と、それぞれの出力の意味を説明します。
- d: ファイルかフォルダか
- rwxrwxr-x: パーミッション
- 2: ハードリンクの数(パーミッションに関係なし)
- ringo: 所有ユーザー
- ringo: 所有グループ(補足:adduserなどでユーザーを作成するとき、同時にユーザー名と同名かつそのユーザーしか入っていないプライベートユーザーグループが作成されます。ここで指定されているのは今説明したプライベートユーザーグループなので、対象は所有ユーザーと同じことになります。)
- 4096: サイズ(パーミッションに関係なし)
- Aug, 9, 01:19: 最終更新日時(パーミッションに関係なし)
- test_dir: ファイル・フォルダ名
パーミッションを理解する上で特に重要なのは上から2つ目のパーミッション、4つ目の所有ユーザー、5つ目の所有グループです。
パーミッションは9桁ありますが3桁ずつに区切られ、それぞれ以下を対象にパーミッションが設定されます。
- 1~3桁: 所有ユーザーに対するパーミッション
- 4~6桁: 所有グループに対するパーミッション
- 7~9桁: 所有ユーザーでもなく所有グループにも属さないユーザーに対するパーミッション
3桁はrwxと表示されており、意味は左から順にread(読み取り権限)、write(書き込み権限)、execute(実行権限)になります。
つまり今回の表示「rwxrwxr-x ringo ringo」は以下を表しています。
- 所有ユーザーのringoに、rwx(読み取り、書き込み、実行)のパーミッションが与えられている
- 所有グループのringoに属すユーザーに、rwx(読み取り、書き込み、実行)のパーミッションが与えられている
- 所有ユーザーでなく所有グループに属さないユーザーに、r-x(読み取り、実行)のパーミッションが与えられている
ここまででの説明で、各パーミッションが誰に対して付与されているものなのかご理解いただけたと思います。
それではここから、rwxで可能になる操作をファイルとフォルダそれぞれ分けて詳しく説明していきます。
ファイルの各パーミッションの意味
読み取り、書き込み、実行それぞれの意味について説明します。フォルダと比較すると直感的に分かりやすいので理解しやすいと思います。
なお最初に話した通りユーザーに対して特定の操作が許可されるか否かはフォルダに対するパーミッションも関係してきます。この章の説明の中コマンド実行例を載せていますが、ファイルに対するパーミッションの違いについて理解しやすくするため、フォルダに対する権限は読み取り・書き込み・実行のすべてが与えられた状態にしています。
ファイルの読み取り
ファイルに記載されている内容を確認するための権限です。
catコマンドなどでファイルに記載されている内容を確認することが出来ます。
ringo@computer:~$ ls -l # 権限の確認(ringoには読み込み権限のみ。それ以外のユーザーは書き込み権限と実行権限をもつ状態)
total 8
-r--r---wx 1 ringo ringo 4 Aug 9 02:20 test_file.txt
ringo@computer:~$ cat test_file.txt # catでファイルの内容を確認できている
can cat
ユーザーringoはtest_fileに対して読み取り権限が付与されているので、ファイルの内容を確認できています。
逆にユーザーotherは読み取り権限が付与されていないので、Permission denied(権限不足による拒否)でファイルの内容を確認できません。
other@computer:/home/ringo$ cat test_file.txt
cat: test_file.txt: Permission denied
ファイルの書き込み
ファイルの内容を変更、追加、削除するための権限です。ファイル自体の追加や削除を可能にする権限ではないことにご注意ください。
viコマンドやechoコマンドを利用してファイルの内容を編集できます。
下は書き込み権限を持つringoによるファイル編集のコマンド実行例です。書き込み権限を持つringoはファイルの編集ができています。
ringo@computer:~$ ls -l # 権限の確認(ringoには書き込み権限のみ。それ以外のユーザーは読み取り権限と実行権限をもつ状態)
total 8
--w--w-r-x 1 ringo ringo 4 Aug 9 02:20 test_file.txt
ringo@computer:~$ echo "dog" > test_file.txt # ファイルの編集(dogという文字の書き込み)
ringo@computer:~$
ユーザーotherは書き込み権限が与えられておらずPermission denied(権限不足による拒否)でファイルの編集ができません。
other@computer:/home/ringo$ echo "usagi" > test_file.txt
bash: test_file.txt: Permission denied
ファイルの実行
シェルスクリプトやバイナリファイルなど実行可能なファイルを実行するための権限です。
Hello, World!と出力するバイナリファイル helloがあります。権限の有無による挙動の違いを確認してみます。
ringo@computer:~$ ls -l # 権限の確認(ringoには実行権限のみ。それ以外のユーザーは実行権限以外をもつ状態)
total 24
---x--xrw- 1 ringo ringo 16696 Aug 10 15:42 hello
ringo@computer:~$ ./hello
Hello, World!
実行権限のみが付与されている状態で実行できました。次に実行権限のみが付与されていないユーザーotherで試してみます。
other@computer:/home/ringo$ ./hello
bash: ./hello: Permission denied
Permission denied(権限不足による拒否)で実行できませんでした。
実行権限についてはもう一つ例を挙げます。「echo 'eco’」と記載されたtest_script.shファイルを準備しました。このファイルを実行できるとecoという文字が出力されます。
ringo@computer:~$ ls -l # 権限の確認(ringoには実行権限のみ。それ以外のユーザーは実行権限以外をもつ状態)
total 24
---x--xrw- 1 ringo ringo 11 Aug 10 15:30 test_script.sh
実行権限が付与されているringoでこのshスクリプトを実行してみます。
ringo@computer:~$ ./test_script.sh
bash: test_script.sh: Permission denied
実行権限を付与しているのにPermission deniedになってしまいました。ここが少しややこしいところなのですが、実は実行対象のファイルの種類によって実行をするために必要な権限が変わります。
最初に紹介したhelloというファイルはコンパイル済みのバイナリファイルであり、マシン(カーネル)が直接解釈できるタイプであったために実行権限があるだけで実行できました。
しかしシェルスクリプトはマシンが直接解釈できるファイルではありません。シェルスクリプトはテキスト形式のファイルであり、その内容はシェル(例えばbashなど)によって読み込まれ解釈されてからはじめて実行可能になります。つまり、シェルスクリプトを実行するためには、シェルがファイルの内容を読み取れる必要があります。またシェルがファイルを読み取るためには実行ユーザーの「読み取り権限」が必要です。
このため、シェルスクリプトを実行するには「実行権限」に加えて「読み取り権限」が必要になるのです。
では読み取り権限も与えてから再度実行してみます。
ringo@computer:~$ ls -l # 読み取りと実行権限がringoに与えられていることを確認
total 24
-r-xr-xrw- 1 ringo ringo 11 Aug 10 15:30 test_script.sh
ringo@computer:~$ ./test_script.sh
eco
無事実行できました。
次に実行権限がないotherの場合の挙動を確認してみます。
other@computer:/home/ringo$ ./hello
bash: ./hello: Permission denied
other@computer:/home/ringo$ ./test_script.sh
bash: ./test_script.sh: Permission denied
バイナリファイルもシェルスクリプトも実行できません。
ややこしい話の中にさらにややこしい話をして申し訳ないのですが、もう一つだけ例を挙げます。
test_script.shに対して読み取り権限はあるが実行権限のないotherユーザーで「bash test_script.sh」を実行するとどのような結果になるでしょうか?
other@computer:/home/ringo$ bash test_script.sh
eco
実行できました。シェルスクリプトに対する実行権限が付いていないのになぜでしょうか?
答えはこのコマンドで実行しているのはあくまでも"bash"であり、"bash"に対しては実行権限を持っていたからです。
bashはシェルスクリプトを解釈して実行する機能を持つ実行可能なファイルです。今の状況を整理すると以下です。
- bashに対しては実行権限がある
- test_script.shに対しては読み取り権限がある
「bash test_script.sh」として場合には、test_script.shから読み取った内容をbashに実行させており、test_script.shを直接実行しているという扱いにはなりません。そのため、「bash test_script.sh」というコマンドの場合には実行が出来たのです。
ちなみに私の環境ではbashの権限は以下のようになっていました。
ringo@computer:~$ ls -l /usr/bin/ |grep bash
-rwxr-xr-x 1 root root 1183448 Apr 18 2022 bash
フォルダの各パーミッションの意味
読み取り、書き込み、実行それぞれの意味について説明します。ファイルと比較するとややこしいです。しかし基本的な考え方として、ファイルにとっての"記載内容"は、フォルダにとっては"直下のファイル・フォルダ"にあたるということを頭に入れておくと理解しやすいです。
フォルダの読み取り
ユーザーが対象フォルダ内にあるファイルやフォルダを一覧表示するための権限です。
権限の有無による挙動の違いを見てみましょう。test_dirというフォルダを作成し、その中にtest_file.txtというファイルを保存してあります。
ringo@computer:~$ ls -l # 権限の確認(ringoには読み取り権限のみ、ringo以外は書き込み権限と実行権限が与えられている)
total 4
dr--r---wx 2 ringo ringo 4096 Aug 10 16:50 test_dir
ringo@computer:~$ ls test_dir/ # フォルダ内にあるファイル・フォルダを確認するコマンドを実行
ls: cannot access 'test_dir/test_file.txt': Permission denied
test_file.txt
test_dirフォルダにあるtest_file.txtがちゃんと表示されています。
※ Permission deniedが出力に存在していますが、これはlsコマンドが単純にフォルダ内を確認しているだけではなく、フォルダ内にあるファイル・フォルダの詳細情報も取得する仕様になっており、今回の場合詳細が取得できなかったために発生しています。フォルダ内のファイル・フォルダの詳細情報を取得するためにはこのあと説明する実行権限が必要になります。
次に読み取り権限のない一般ユーザーで試してみます。
other@computer:/home/ringo$ ls test_dir/
ls: cannot open directory 'test_dir/': Permission denied
権限不足で表示できないことを確認できました。
フォルダの実行
ファイルが対象の時には書き込み権限を先に説明しましたが、フォルダの権限の場合、実行権限が書き込み権限に大きくかかわってくるために先に実行権限について説明します。フォルダの権限の中で一番分かりにくいのに、最も重要な役割を持っています。
フォルダに対する実行権限は「フォルダにアクセスする」「フォルダ内のファイル・フォルダにアクセスする」ために求められる権限です。
まず分かりやすい「フォルダにアクセスする」について権限有無による挙動の違いを見てみましょう。
ringo@computer:~$ ls -l # 権限の確認(ringoには実行権限のみ、ringo以外には読み取り権限と書き込み権限が与えられている)
total 4
d--x--xrw- 2 ringo ringo 4096 Aug 10 19:27 test_dir
ringo@computer:~$ cd test_dir/
ringo@computer:~/test_dir$
アクセスできました。それでは実行権限を持たないユーザーotherで試してみます。
other@computer:/home/ringo$ cd test_dir/
bash: cd: test_dir/: Permission denied
権限不足でアクセスできないことを確認できました。
次に「フォルダ内のファイル・フォルダにアクセスする」について説明します。こちらがややこしく厄介です。なぜ厄介なのかというと他のファイルやフォルダの権限と組み合わさって効果を発揮するからです。
この役割のイメージは対象フォルダ内の各ファイル・フォルダに対する入館証です。
まだピンとは来ていないと思いますので具体的にコマンドで例を挙げます。
先ほどから利用しているtest_dirフォルダの直下にtest_file.txtというファイルを作りました。test_file.txtへの読み取り権限を持った状態で、test_dirに対する実行権限の有無によってどんな挙動の違いが生まれるのかを見てみます。
test_dir # ここの実行権限有無による挙動の違いを確認
└── test_file.txt # 読み取り権限あり
まずはtest_dirに対して実行権限を持ったユーザーringoの場合。
$ ls -l # 権限の確認。ringoには実行権限のみ、ringo以外は読み取り権限と書き込み権限が与えられている
total 4
d--x--xrw- 2 ringo ringo 4096 Aug 10 19:27 test_dir
ringo@computer:~$ cat test_dir/test_file.txt # ファイルの内容確認
dog
表示できました。では次にtest_dirに対して実行権限を持たないユーザーotherの場合。
other@computer:/home/ringo$ cat test_dir/test_file.txt # ファイルの内容確認
cat: test_dir/test_file.txt: Permission denied
ファイルには読み取り権限が付いているのにエラーになりました。これはなぜかというとユーザーotherはtest_dirに対する実行権限を持っておらず、test_dirの下にあるtest_file.txtにアクセスできていないためです。
ファイルやディレクトリに対する操作は「①対象へのアクセス」「②操作」の順番で行われます。操作対象にアクセスできないのであれば操作ができません。この"操作対象へのアクセスを可能にする権限"がフォルダに対する実行権限です。
またこのような性質からアクセスしたいフォルダやファイルがあったとき、その親のディレクトリすべてに実行権限が付いている必要があります。どこか途中で一つでも実行権限が付いていなければその下のフォルダにアクセスできなくなってしまうからです。
なお対象フォルダ内にファイルを作成したり、削除したりするのにもフォルダに対する実行権限が必要ですが、これはフォルダに対する書き込み権限と強く関連するのでこれから説明するフォルダの書き込み権限の章で詳しく話します。
フォルダの書き込み
ユーザーが対象フォルダ内にあるファイルやフォルダを作成・削除・名称変更するための権限です。いずれの操作も実行権限も持っていないと実現できず書き込み権限を単体で持つ意味はありません。
まず削除について説明します。早速権限の有無による挙動の違いを見てみましょう。test_dirフォルダの直下にtest_file.txtというファイルを作りました。test_file.txtに対しては何も権限を持たない状態で、test_dirに対する書き込み権限の有無によってどんな挙動の違いが生まれるのかを見てみます。
test_dir # 実行権限ありで、書き込み権限有無による挙動の違いを確認
└── test_file.txt # すべての権限が付いていない状態
書き込み権限を持ったユーザーringoでtest_file.txtの削除を試します。
ringo@computer:~$ ls -l # 権限の確認。ringoには実行と書き込み権限、ringo以外は実行権限と読み取り権限が与えられている
total 4
d-wx-wxr-x 2 ringo ringo 4096 Aug 10 21:25 test_dir
ringo@computer:~$ rm test_dir/test_file.txt # ファイルを削除するコマンドを実行
rm: remove write-protected regular file 'test_dir/test_file.txt'? yes
ringo@computer:~$
削除することが出来ました。
次に書き込み権限のない一般ユーザーで試してみます。なおtest_file.txtは消してしまったので再度作り直しています。
other@computer:/home/ringo$ rm test_dir/test_file.txt
rm: remove write-protected regular empty file 'test_dir/test_file.txt'? yes
rm: cannot remove 'test_dir/test_file.txt': Permission denied
権限不足で削除できないことを確認できました。
念のため実行権限の有無が本当に影響を与えているのかについても検証しておきます。test_dirに書き込み権限のみがある状態で削除を試してみます。
ringo@computer:~$ ls -l # 権限の確認。ringoには書き込み権限のみ
total 4
d-w--w-r-x 2 ringo ringo 4096 Aug 11 11:47 test_dir
ringo@computer:~$ rm test_dir/test_file.txt
rm: cannot remove 'test_dir/test_file.txt': Permission denied
権限不足により削除できませんでした。これはファイル自体の削除という操作をするためには「対象フォルダにアクセスする」ステップが必要だからです。対象フォルダにアクセス出来てはじめて対象フォルダ内の構造(フォルダ・ファイルの配置や存在)の操作が可能になります。そして「対象フォルダにアクセスする」ためには実行権限が必要です。
ファイル削除について必要なステップと必要な権限をまとめると以下です。
- 削除対象ファイルが存在するフォルダにアクセスするステップ(実行権限が必要)
- 削除対象ファイルを削除するステップ(書き込み権限が必要)
なお、フォルダ・ファイルの操作をするためにフォルダに入る必要があるのは作成と名称変更も同様です。
それぞれコマンド実行結果を載せます。まずは書き込みと実行権限がある場合。
ringo@computer:~$ ls -l # 権限の確認。ringoには書き込み権限と実行権限が与えられている
total 4
d-wx-wx--- 2 ringo ringo 4096 Aug 11 11:47 test_dir
ringo@computer:~$ touch test_dir/create_file.txt # ファイル作成(エラーが発生せず成功している)
ringo@computer:~$
ringo@computer:~$ mv test_dir/create_file.txt test_dir/change_name.txt # ファイル名変更(エラーが発生せず成功している)
ringo@computer:~$
ファイル作成と名前変更のどちらも問題なく実行できています。
次に書き込み権限のみの場合。
ringo@computer:~$ ls -l # 権限の確認。ringoには書き込み権限のみが与えられている
total 4
d-w--w---- 2 ringo ringo 4096 Aug 11 16:48 test_dir
ringo@computer:~$ touch test_dir/create_file.txt # ファイル作成(エラーが発生)
touch: cannot touch 'test_dir/create_file.txt': Permission denied
ringo@computer:~$ mv test_dir/test_file.txt test_dir/change.txt # ファイル名変更(エラーが発生)
mv: failed to access 'test_dir/change.txt': Permission denied
いずれも権限不足のエラーが起きています。
次に実行権限のみの場合。
ringo@computer:~$ ls -l # 権限の確認。ringoには実行権限が与えられている
total 4
d--x--x--- 2 ringo ringo 4096 Aug 11 16:51 test_dir
ringo@computer:~$ touch test_dir/create_file.txt # ファイル作成(エラーが発生)
touch: cannot touch 'test_dir/create_file.txt': Permission denied
ringo@computer:~$ mv test_dir/test_file.txt test_dir/change.txt # ファイル名変更(エラーが発生)
mv: cannot move 'test_dir/test_file.txt' to 'test_dir/change.txt': Permission denied
権限不足のエラーが起きました。
このようにフォルダの書き込み権限は実行権限がセットでないと意味を持ちません。
まとめ
中級エンジニアでもきちんと理解できていないことが多いパーミッションについて説明いたしました。ファイルに対する権限は多くの方が理解できていると思うのですが、フォルダの権限の方は複雑であり正確に理解できている人は滅多にいません。
この記事では特にややこしい、しかしとても重要なフォルダに対する実行権限と書き込み権限について詳しく説明いたしました。
一度で完璧に理解することは難しいかもしれませんが、理解できるまで読んでいただき適切な権限設定をできるようになってもらえたら嬉しいです。