Linux基礎コース(パート1)8/9
ファイルとパーミッション
こちらの記事では、ファイルの種類やパーミッションについて解説します。
基本的なファイルの種類とパーミッションの設定方法を学ぶことで、より安全なファイル管理が可能になります。
Linuxファイルには大きく分けて通常ファイルとスペシャルファイル(特殊ファイルとも、以降スペシャルファイルで統一)の2つの主要なファイルタイプが存在します。それぞれのファイルタイプについて解説していきます。
通常ファイル
一般的に扱うことの多いファイルで、読み込み・書き込み・実行が可能なファイルを指します。ファイルの種類を表す先頭の記号は-(ハイフン)です。
# 'sample.txt'という空ファイルを作成します。
touch sample.txt
# ファイルの詳細を確認します。
ls -l sample.txt
-rw-r--r--  1 envader redavne    0 May 17 05:07 sample.txtLinuxにおけるファイルの分類には、通常ファイルとスペシャルファイルの二つがありますが、ディレクトリもまた独自の分類として扱うことが多いです。ディレクトリはWindowsでいうところの「フォルダ」に相当し、複数のファイル(通常ファイルやスペシャルファイルなど)を格納するための特殊な形のファイルと言えます。Linuxでディレクトリを示すための記号は「d」です。
# 'test_dir'というディレクトリを作成します。
mkdir test_dir
# ディレクトリの詳細を確認します。
ls -l
drwxr-xr-x 2 envader redavne 4096 May 17 05:15 test_dirリンクファイルもまた通常ファイルの一種です。リンクファイルは、元のファイル(ファイルの実体)に対する参照として機能します。リンクファイルには、ハードリンクとシンボリックリンクの2種類があります。
ハードリンク は、元のファイルと同じinode(index node)とinode番号を持つリンクファイルです。つまり、ハードリンクは元のファイルと同等の存在であり、名前以外の点ではほぼ区別がつきません。
なお、Linuxのファイルシステムでは、「ファイルの中身のデータ」と「ファイルの属性や管理情報」が別々に管理されています。後者の情報は、ディスクのinodeという管理領域に格納され、ファイルがディスクに保存される際には、それぞれに一意のinode番号が割り当てられます。
# 'testfile'という名前のファイルを作成します。
touch testfile
# 'testfile'のハードリンク('h_link')を作成します。
ln testfile h_link
# 元のファイルと同じinode番号(190365)が割り振られていることを確認します。
ls -li
190365 -rw-r--r--  2 envader redavne    9 May 17 05:29 testfile
190365 -rw-r--r--  2 envader redavne    9 May 17 05:29 h_link一方、 シンボリックリンク は、ハードリンクとは対照的に ソフトリンク とも呼ばれます。
シンボリックリンクはリンク元のファイルへのポインタとして機能します。つまり、元のファイルの存在する場所を示しており、Windowsのショートカットとほぼ同等の存在です。
ls コマンドを使用してシンボリックリンクを表示すると、リンク元のファイルの場所が末尾に表示されます。
また、シンボリックリンクを示す先頭の記号は「l」です。
なお、シンボリックリンクのパーミッションは一見すると「rwxrwxrwx」(全ユーザーに全ての権限が与えられているように見える)と表示されますが、実際の挙動はリンク元のファイルのパーミッションに従います。
# lnコマンドに-sオプションを指定して、シンボリックリンクを作成します。
ln -s testfile s_link
# 元のファイルとは異なるinode番号が割り振られています。
ls -li
190365 -rw-r--r--  2 envader redavne    9 May 17 05:29 h_link
190365 -rw-r--r-- 2 envader redavne    9 May 17 05:29 testfile
190351 lrwxrwxrwx 1 envader redavne    11 May 17 05:32 s_link -> testfile【TIPS】Linuxコマンドも通常ファイル
Linuxコマンドの実態は、特定の操作を実行するための実行ファイルです。通常ファイルは「読み込み・書き込み・実行が可能なファイル」と先述した通り、これに実行ファイルも含まれます。ですから、Linuxコマンドを実行する際、実際にはそのコマンドに対応する実行ファイルが動作することになります。
実際に、cat コマンドを例に確認してみましょう。
# whichコマンドで、catコマンドの実態(実行ファイル)のパスを確認します。
which cat
/usr/bin/cat
# 先頭の記号が-(ハイフン)となっていることから、実行ファイルが通常ファイルであることがわかります。
ls -l /usr/bin/cat
-rwxr-xr-x 1 root root 43416 Sep  5  2019 /usr/bin/catスペシャルファイル
スペシャルファイルは大きく分けていくつかの種類があります。
デバイスファイル
コンピュータではさまざまなデバイスを利用します。たとえば、ハードディスク・SSD・DVDドライブ・USB等です。これらのデバイスを操作するために、Linuxではデバイスに対応したデバイスファイルという特別なファイルが用意されています。
デバイスへの入出力は、このデバイスファイルを通じて行われます。つまり、デバイスファイルがあることで、他のファイルと同様にデバイスにアクセスすることが可能になります。
デバイスファイルには、 ブロックデバイス と キャラクタデバイス の2つがあります。
- 
ブロックデバイス(block-device) ブロックという単位でデータ転送を行うデバイスを指します。ハードディスク・CD-ROM・フラッシュメモリ等がブロックデバイスに分類されます。lsコマンドでブロックデバイスを表す先頭の記号は b です。 
- 
キャラクタデバイス(character-device) 一文字ずつ(キャラクタ)データ転送を行うデバイスを指します。キーボード・マウス・ターミナル等がキャラクタデバイスに分類されます。 lsコマンドでキャラクタデバイスを表す先頭の記号は c です。
デバイスファイルは主に /dev 配下に格納されています。
# /dev配下を確認します。
ls -l /dev
....
brw-r-----   1 root     operator   0x1000000  5 27 06:17 disk0
....
crw-rw-rw-   1 root     wheel      0x2000000  6  8 22:58 tty
....パイプ
パイプは複数のコマンドを繋ぐために使われる特殊なファイルのひとつです。パイプは無名ファイルであるため、ファイルシステム上に実態を持ちません。無名ファイルであるパイプは使用後に消えてしまいますが、実態のあるファイルとして名前付きパイプを作成することもできます。
名前付きパイプを表す先頭の記号はpです。
# 名前付きパイプを作成するには、mkfifoコマンドを使用します。
mkfifo sample_pipe
$ ls -l
prw-rw-r--  1 envader redavne    0 May 18 02:56 sample_pipeソケット
ソケットは通信の窓口となるファイルです。パイプと同様に無名ファイルであるため、基本的にはファイルシステム上ではその実態が確認できません。しかし、実態のあるファイルとして名前付きソケットを作成することができます。
例としてTmuxのソケットファイルを確認してみます。Tmuxをインストールすると/tmpディレクトリにtmux-1000/defaultというデフォルトのソケットファイルが作成されます(参照:Advanced Use・tmux/tmux Wiki)。TmuxがTmuxサーバーと通信する際に使用されるのがこのソケットになります。
ソケットファイルを表す先頭の記号はsです。
# Tmuxのソケットファイルを確認します。
ls -l /tmp/tmux-1000/default
srwxrwx--- 1 envader redavne 0 May 16 02:23 tmux-1000/default※ Tmuxは、端末多重化装置(Termial Multiplexer)です。
Envaderでは、すべてのターミナルでTmuxを起動しています。Envaderのターミナルカスタマイズコースの次の記事では、実際に手を動かしながらTmuxを学習できます。
https://envader.plus/course/7/scenario/1044
所有者と所有グループ
全てのファイルにはそのファイルの所有者と所有グループが決まっています。ファイルを作成すると、作成したユーザーとプライマリグループがそれぞれファイルの所有者と所有グループに割り当てられます。
※ Linuxにおけるグループには、基本的なグループであるプライマリグループとその他に属しているサブグループがあります。特定のユーザーのプライマリグループは、/etc/passwdファイルのGIDフィールドで確認できます。
下の例ではsample.txtの所有者がenvader、所有グループがredavneとなっています。
ls -l
-rw-r--r--  1 envader redavne    0 May 17 05:07 sample.txtchownコマンド
chown(change owner)はファイルの所有者(owner)を変更するためのコマンドです。
chownコマンドを実行するにはroot権限が必要です。
ls -l
-rw-r--r--  1 envader redavne    0 May 17 05:07 sample.txt
# sudoコマンドを使うと一時的にroot権限が付与されます。
# 書式: chown [新たなユーザー名] [変更するファイル名]
sudo chown deenvar sample.txt
-rw-r--r--  1 deenvar redavne    0 May 17 05:07 sample.txtまた、所有者と所有グループを同時に変更することもできます。
ls -l
-rw-r--r--  1 envader redavne    0 May 17 05:07 sample.txt
# 新たなユーザー名とグループ名を:(コロン)で繋いで指定します。
sudo chown deenvar:envader sample.txt
-rw-r--r--  1 deenvar envader    0 May 17 05:07 sample.txtディレクトリ配下のファイルやディレクトリの所有者を変更する場合は、-R(--recursive)オプションを指定します。
chgrpコマンド
chgrp(change group)はファイルの所有グループを変更するためのコマンドです。chgrpコマンドは一般ユーザーでも実行できますが、その場合に設定可能なグループはそのユーザーが属しているグループに限定されます。それ以外のグループを指定する場合はroot権限が必要となります。
ls -l
-rw-r--r--  1 envader redavne    0 May 17 05:07 sample.txt
# 書式: chgrp [新たなグループ名] [変更するファイル名]
chgrp envader sample.txt
-rw-r--r--  1 envader envader    0 May 17 05:07 sample.txtなお、ディレクトリの所有グループを変更する場合は-Rオプションを指定します。
パーミッションについて
ファイルやディレクトリには様々な権限(パーミッション)があります。それらを適切に付与することで安全なファイル管理が可能になります。権限には基本的なパーミションと特殊なパーミッションが存在します。
基本的なパーミッション (r/w/x)
ファイルやディレクトリには r (read: 読み込み権限)、 w (write: 書き込み権限)、 x (execute: 実行権限)という3つの基本的なパーミッションを設定できます。また、以下のように r w xそれぞれには数字が割り当てられています。
| 権限 | 数字 | 
|---|---|
| r (read) | 4 | 
| w (write) | 2 | 
| x (execute) | 1 | 
sample.txtを例に考えてみましょう。
ls -l
-rw-r--r--  1 envader redavne    0 May 17 05:07 sample.txt左端の-は通常ファイルを表します。次から3文字ずつrw-が所有者、r--がグループ、r--がその他のユーザーのパーミッションを表しています。このsample.txtのパーミッションを数字で表現すると、r+w(4+2)  r(4)  r(4)で「644」になります。
chmodコマンド
chmod(change mode)はファイルへのアクセス権限を変更するためのコマンドです。一般ユーザーでも自分が所有するファイルの権限を変更することができますが、他のユーザーが所有するファイルの権限を変更するにはroot権限が必要です。 chmod コマンドでは下の表のような記号やアルファベットを扱います。
「対象」とは、”何に対して”権限を与えるかを示します。
| 対象 | 説明 | 
|---|---|
| u (users) | 所有者 | 
| g (groups) | グループ | 
| o (others) | その他のユーザー | 
| a (all, all users) | すべてのユーザー | 
「操作記号」とは、対象の権限を”どうするか”を示します。
| 操作記号 | 説明 | 
|---|---|
| + | 追加する | 
| - | 削除する | 
| = | 指定する | 
「権限」とは、”どの権限か”を示します。
| 権限 | 説明 | 
|---|---|
| r・w・x | 読み・書き・実行 | 
| s | SUID・SGID | 
| t | スティッキービット | 
次に、chmodコマンドの「記号で指定する方法」と「数字で指定する方法」の2つの使い方を見ていきましょう。
ls -l
-rw-r--r--  1 envader redavne    0 May 17 05:07 sample.txt
# 記号で指定する方法で、所有者とグループにx(実行権限)を付与します。
sudo chmod ug+x sample.txt
-rwxr-xr--  1 envader redavne    0 May 17 05:07 sample.txt
# 数字で指定する方法で、すべてに全権限(r,w,x)を付与します。
sudo chmod 777 sample.txt
-rwxrwxrwx  1 envader redavne    0 May 17 05:46 sample.txtumaskコマンド
ファイルやディレクトリが作成されるとき、そのデフォルトのパーミッションはumask値を用いて決定されます。umask(user file-creation mode mask)はumask値(ファイルが作成されたときにデフォルトで付与されるパーミッション)を変更・設定するためのコマンドです。
現在のumask値を確認します。
umask
022上の例では3桁で表示されていますが、4桁で表示されることもあります。その場合は下3桁がr w xが設定される部分に該当します。umask値からパーミッションを計算する場合、ファイルの場合は 666 から、ディレクトリの場合は 777 からumask値を引きます。この例のようにumask値が022の場合のパーミッションは、ファイルでは「644」(=666-022)、ディレクトリでは「755」(=777-022)になります。
次に、umask値を変更しましょう。
umask 002
touch maskfile
mkdir mask_dir
ls -l
drwxrwxr-x  2 envader redavne 4.0K May 17 05:51 mask_dir
-rw-rw-r--  1 envader redavne    0 May 17 05:51 maskfileumask値を「022」から「002」に変更したことで、新たに作成したファイル(maskfile)のパーミッションが「664」(=666-002)に、ディレクトリ(mask_dir)は「775」(=777-002)になっています。
特殊なパーミッション (SUID/SGID/スティッキービット)
特殊なパーミッションにはSUID ・SGID ・スティッキービット の3種類があります。
ユーザーがパスワードを変更する場合を考えてみましょう。passwdコマンドでパスワードを変更すると、/etc/passwdファイルの該当箇所が書き換えられます。
まずは/etc/passwdファイルを確認してみましょう。
ls -l /etc/passwd
-rw-r--r-- 1 root root 1837 May 15 04:36 /etc/passwd所有者はrootユーザーになっており、他のユーザーやグループに書き込み権限は与えられていません。しかし、/etc/passwdファイルは一般ユーザーにでも更新可能となっています。
それでは、passwdコマンドを確認してみましょう。
which passwd
/usr/bin/passwd
$ ls -l /usr/bin/passwd
-rwsr-xr-x 1 root root 68208 Jul 15  2021 /usr/bin/passwd所有者の実行権限がsになっています。これをSUID (Set User ID)といいます。SUIDが設定されたファイルは、ファイル所有者の権限で実行されます。つまり、今回の例の場合は一般ユーザーとして実行したとしても、実際はrootユーザーの権限で実行されています。これがグループに付与されている場合はSGID (Set Group ID)といいます。
実際にSUID・SGIDを設定してみましょう。
ls -l
-rw-r--r--  1 envader redavne    0 May 17 05:07 sample.txt
# 記号でSUIDを設定します。
sudo chmod u+s sample.txt
ls -l
-rwSr--r--  1 envader redavne    0 May 17 05:58 sample.txt
# 数字で設定する場合は、4000を指定します。
sudo chmod 4744 sample.txt
ls -l
-rwsr--r--  1 envader redavne    0 May 17 05:58 sample.txt
---------------------------------------------------------------
ls -l
-rw-r--r--  1 envader redavne    0 May 17 05:07 sample.txt
# 記号でSGIDを設定します。
sudo chmod g+s sample.txt
ls -l
-rw-r-Sr--  1 envader redavne    0 May 17 05:59 sample.txt
# 数字で設定する場合は、2000を指定します。
sudo chmod 2674 sample.txt
ls -l
-rw-rwsr--  1 envader redavne    0 May 17 05:59 sample.txtSUID・SGIDを設定する際に、予め所有者や所有グループに実行権限xがある場合には小文字のs、ない場合には大文字のSが付与されます。
次に、/tmpディレクトリを確認してみます。
ls -l /tmp
drwxrwxrwt 109 root root  20K May 17 02:52 tmpその他のユーザーの実行権限がtになっています。これをスティッキービット(sticky bit) といいます。スティッキービットはディレクトリに設定されるパーミッションです。スティッキービットが設定されたディレクトリには、書き込み権限はありますが、自分以外のユーザーが所有者となっているファイルを削除することはできません。/tmpディレクトリでは、全てのユーザーに書き込み権限が付与されていますが、スティッキービットが設定されていることで、/tmp配下に自分以外のユーザーが作成したファイルは削除できません。
実際にスティッキービットを設定してみましょう。
まずはディレクトリを作成します。
mkdir sample_dir
ls -ld sample_dir
drwxr-xr-x  2 envader redavne 4096 Jul 25 12:34 sample_dir次に、スティッキービットを設定します。
# 記号でスティッキービットを設定します。
sudo chmod o+t sample_dir
ls -ld sample_dir
drwxr-xr-t  2 envader redavne 4096 Jul 25 12:34 sample_dir
# 数字で設定する場合は、1000を指定します。
sudo chmod 1755 sample_dir
ls -ld sample_dir
drwxr-xr-t  2 envader redavne 4096 Jul 25 12:34 sample_dirこの例では、まず新しいディレクトリ sample_dir を作成します。デフォルトでは、ディレクトリのパーミッションは drwxr-xr-x となります。次に、chmod o+t sample_dir コマンドでスティッキービットを設定します。その結果、ディレクトリのパーミッションは drwxr-xr-t となります。ここで t はスティッキービットを表します。
最後に、 chmod 1755 sample_dir コマンドで数値を使用してスティッキービットを設定します。ここで、 1 はスティッキービットを表し、755 はそれぞれ所有者、グループ、その他のユーザーのパーミッションを表します。このコマンドを実行した後も、ディレクトリのパーミッションは drwxr-xr-t となり、スティッキービットが設定されていることが確認できます。
まとめ
ファイルの種類やパーミッションについて解説しました。ファイルのアクセス権(パーミッション)を適切に設定することは、安全なファイル管理に欠かせません。
問題を解くためには、十分な画面サイズのPC環境をご利用下さい。
