/ 2023/07/02 訂正
/ ご指摘を受けまして、おっしゃりますとおり、
/ 普通(通常)のファイルの説明について
/ 考察が欠けておりましたので訂正いたします
/ 失礼いたしました
.
[ 1. 疑問 ]
bash のサンプルコードで、
if [ -f test.txt ]; then
というファイルチェックコードがあり、
bash というか linux OS レベルにおいて
-f オプションの意味を
ネットで調べてみましたが、
・ファイルなら true
・普通のファイルなら true
という答えがおおむねで、
この、普通のファイル(通常のファイル) とは何ぞや
という具体的な意味をいまさらですが、知りたくて
ChatGPT 先生に聞いてみました
※広義には unix になると思いますが、
ディストリビューションによって違いはあるかもです
[ 2. 質問(1) ]
bash の if 文で、ファイル オプションに
-f が使われている場合、
普通のファイルなら true
とありますが、普通のファイルとは、
どういう意味ですか?
-e の ファイルが存在するなら true
との違いを教えてください
[ 3. 回答(1) ]
Bashの if 文で -f オプションが使われる場合、
-f はファイルが存在し、かつ
普通のファイル(通常のテキストファイルやバイナリファイル)
である場合に条件を満たします
つまり、 -f オプションはファイルの存在と同時に、
それがディレクトリや特殊ファイル(デバイスファイルなど)
ではないことを確認します
一方、 -e オプションはファイルが存在する場合に条件を満たします
これにはディレクトリや特殊ファイルも含まれます
つまり、ファイルが存在するかどうかだけを確認し、
ファイルの種類には関係しません
例えば、以下のようなシェルスクリプトがあったとします:
#!/bin/bash
filename="example.txt"
if [ -f "$filename" ]; then
echo "The file exists and is a regular file."
fi
if [ -e "$filename" ]; then
echo "The file exists."
fi
もし example.txt が普通のテキストファイルであれば、
上記のスクリプトは両方の条件を満たし、
両方のメッセージを表示します
しかし、もし example.txt がディレクトリだった場合、
-f 条件は満たしませんが、 -e 条件は満たします
[ 4. 疑問のつづき ]
> 普通のファイルとは
> 通常のテキストファイル や バイナリファイル で、
> ディレクトリや特殊ファイル(デバイスファイルなど)ではない
> -e オプションは
> ディレクトリや特殊ファイルも含まれる
> (-e はファイル専用ではないので、ディレクトリでも存在すれば true)
という回答でした
-f と -e でチェック内容が異なるので、違いがでるケースがある、
ということで、-f と -e の違いの説明としては
間違っていないと思います
> 普通のファイルとは
> 通常のテキストファイル や バイナリファイル で、
ここの部分は断定せず、後述します
続いて、同じようなことを思っている方の記事を見てみます
[ 5. regular file とは(1) ]
What is a Regular File ?
https://www.javatpoint.com/what-is-a-regular-file
(要約)
普通(通常)のファイルとは、
システムまたはユーザーが作成したデータを含む
特定のファイル形式(レイアウト、プロパティ、ファイルフォーマット等)で
生成されたファイルの一種
cp、mv、rm、cat などの
コマンドやユーティリティを使って操作することができる
一般的には、ファイル拡張子で判断できるものであるが、
ファイル拡張子がない場合もある
普通(通常)ではないファイルとは
ディレクトリ、特殊ファイル(デバイス・ファイル)、
シンボリック・リンクなどがある
[ 6. regular file とは(2) ]
What is a regular file ?
https://unix.stackexchange.com/questions/99276/what-is-a-regular-file
(要約)
・test コマンドで、通過できるものは、普通(通常)のファイル となる
・stat コマンドでも、普通(通常)のファイル のチェックが可能
・stat() 関数で、普通(通常)のファイルと
他のファイルタイプの違いについての識別がわかります
(st_mode という項目で以下の判断をすることが可能です)
S_IFMT 0170000 bit mask for the file type bit fields
S_IFSOCK 0140000 socket
S_IFLNK 0120000 symbolic link
-----------------------------------------
S_IFREG 0100000 regular file
-----------------------------------------
S_IFBLK 0060000 block device
S_IFDIR 0040000 directory
S_IFCHR 0020000 character device
S_IFIFO 0010000 FIFO
S_ISUID 0004000 set UID bit
S_ISGID 0002000 set-group-ID bit (see below)
S_ISVTX 0001000 sticky bit (see below)
S_IRWXU 00700 mask for file owner permissions
S_IRUSR 00400 owner has read permission
S_IWUSR 00200 owner has write permission
S_IXUSR 00100 owner has execute permission
S_IRWXG 00070 mask for group permissions
S_IRGRP 00040 group has read permission
S_IWGRP 00020 group has write permission
S_IXGRP 00010 group has execute permission
S_IRWXO 00007 mask for permissions for others (not in group)
S_IROTH 00004 others have read permission
S_IWOTH 00002 others have write permission
S_IXOTH 00001 others have execute permission
statコマンドを試してみました
(例:.deb / debian パッケージファイル)
$ stat google-chrome-stable_current_amd64.deb
File: google-chrome-stable_current_amd64.deb
Size: 82967408 Blocks: 162048 IO Block: 4096 regular file
Device: 2h/2d Inode: 168603511049686871 Links: 1
Access: (0644/-rw-r--r--) Uid: ( 1000/ usera) Gid: ( 1000/ usera)
Access: 2022-09-19 20:52:59.320756300 +0900
Modify: 2022-03-29 21:53:06.000000000 +0900
Change: 2022-09-19 20:51:55.812595900 +0900
Birth: -
Size: 行の最後に regular file と表示されてますね
ちょっと角度を変えて「普通(通常)ではないファイル」
について、質問してみました
[ 7. 質問(2) ]
linux OS においての
「普通(通常)ではないファイル」とは
どういったファイルのことですか?
[ 8. 回答(2) ]
「普通(通常)ではないファイル」とは、
ディレクトリやシンボリックリンク、デバイスファイル、
パイプ、ソケット、FIFOなど、通常のデータを格納するための
ファイル(通常ファイル)以外の特殊なファイルのことを指します
具体的なファイルの種類は以下のようになります:
- ディレクトリ(Directory): ファイルやサブディレクトリの
コンテナとして機能する特殊なファイル
- シンボリックリンク(Symbolic Link): 他のファイルや
ディレクトリへの参照を保持する特殊なファイル
- デバイスファイル(Device File):
ハードウェアデバイスへのアクセスを提供する特殊なファイル
キャラクタデバイスやブロックデバイスなどが含む
- パイプ(Pipe): プロセス間の通信に使用される特殊なファイル
- ソケット(Socket): ネットワーク通信や
プロセス間通信(IPC)のための特殊なファイル
- FIFO(First In, First Out): プロセス間の通信に
使用される名前付きパイプ
[ 9. 普通(通常)ではないファイルの割り出し ]
「普通(通常)ではないファイル」について、おおむね間違いではなさそうですが、
さらにファイルの種別について ls コマンドにて確認してみます
ls コマンドでも、stat コマンド同様に、
パーミッション情報の前の先頭の文字列で、ファイルの種別が確認できます
- : regular file
d : directory
c : character device file
b : block device file
s : local socket file
p : named pipe
l : symbolic link
$ ls -ld google-chrome-stable_current_amd64.deb
-rw-r--r-- 1 usera usera 82967408 Mar 29 2022 google-chrome-stable_current_amd64.deb
-> regular file
$ ls -ld /dev/null
crw-rw-rw- 1 root root 1, 3 Jun 30 02:40 /dev/null
-> character device file
・regular file
通常ファイルは、Linuxシステムで最も一般的なファイル・タイプである
テキスト・ファイル、イメージ、バイナリ・ファイル、共有ライブラリ等
-> touch や echo コマンド (または vim, cat, リダイレクション) で作成
・directory
Linuxにおいて、ディレクトリとは、
Windowsのような「入れ物」(フォルダ)単体を表す名称と言うよりも
ルートディレクトリ、カレントディレクトリといった、
「所在」や「階層」などの「位置」概念の意味合いを持つファイル・タイプ
(WindowsでもCドライブは階層的概念はあるが他のドライブは任意階層となる)
-> mkdir コマンドで作成
・character device file
・block device file
ユーザーやプログラムがハードウェア周辺機器と通信することを
可能にするファイルで、キャラクタデバイス
(またはキャラクタスペシャルファイル)は、
システムが一文字ずつデータを転送するバイトストリーム型機器
(キーボードやマウス,シリアル・インタフェースなど)を扱う
対して、ブロック・デバイスは、ブロック形式でデータを
やり取りする機器に対応し、
(主にハードドライブ/CD-ROMドライブ/メモリ領域等のハードウェアを管理する)
一般にバッファを使った入出力を行う
-> mknod コマンドで作成
・local socket file
ソケットは、同一コンピュータ上のプロセス間ので通信
(IPC:Inter-Process Communication) を行うためのインタフェースの一種で、
ソケットファイルは、それらの通信を行うための拠点となる特殊なファイル
-> ソケットファイルは単体コマンドで作成するものではなく、
socketシステムコールを使用して ソケットが作成され、
bindシステムコールで、ソケットに名前をつけたら、
ファイルシステム上で ls で確認可能となる
・named pipe
名前付きパイプは
無名パイプ(コマンド間の入出力を繋げるプロセス間通信の一種で、
使用しているプロセスが動作中のみ存在する)を拡張したもので、
名前付きパイプはファイルシステム上にファイルとして扱うことが可能
-> mkfifo コマンドで作成
・symbolic link
シンボリックリンクは、元のファイルへのポインタとして
本体を参照できるように実体へのファイルパスだけを保持したファイル
-> ln -s コマンドで作成
これらの stat や ls コマンドから「普通(通常)ではない」ファイルとは、
以下の種類となり、
・bit mask for the file type bit fields
・socket
・symbolic link
・block device (/dev/sda 等)
・directory
・character device (/dev/null, /dev/tty1, /dev/random 等)
・FIFO (名前付きパイプ)
・set UID bit
・set-group-ID bit (see below)
・sticky bit (see below)
・mask for file owner permissions
・owner has read permission
・owner has write permission
・owner has execute permission
・mask for group permissions
・group has read permission
・group has write permission
・group has execute permission
・mask for permissions for others (not in group)
・others have read permission
・others have write permission
・others have execute permission
それら以外が「普通(通常)のファイル」ということになります
[ 10. 普通(通常)のファイルとは ]
では「普通(通常)のファイル」についてみていきます
これまで述べてきた中で「普通(通常)のファイル」とは、
・テキストファイル、画像などのイメージファイル、バイナリファイル等
・touch や echo コマンド で作成できるファイル
・cp、mv、rm、cat などのコマンドを使って操作することができる
ということになりますが、大前提となる ファイルシステム、および、
ファイルシステムが管理する ファイル を踏まえて述べていきます
「ファイルシステム」
ハードディスクなどの記憶媒体の保存領域に
ディレクトリの階層構造を用いてデータを記録(保存)・管理するための仕組み
「ファイル」
記録(保存)・管理される情報の単位(塊) を「ファイル」と呼ぶ
「普通(通常)のファイル」 (regular file) は、ファイルシステムにおいて
特定のファイルタイプとして明示的に分類されない
一般的なデータファイルを指します
ファイルシステムでは、ファイルタイプに応じて異なる特性や
操作方法が提供され、前述したディレクトリやシンボリックリンク等の
「普通(通常)ではない」ファイルは、特殊ファイルとして、
それぞれ独自のファイルタイプとして識別され、
特別な操作や動作が可能です
一方「普通(通常)のファイル」は特定のファイルタイプとして
明示的に指定されず、そのファイルの内容によって解釈されるものになります
具体的には、通常のデータファイルとして扱われ、
テキストファイルやバイナリファイル、画像ファイル、音声ファイルなど、
さまざまな種類のデータを格納できます
ファイルシステムはこれらのファイルの内容に対して
特定の操作を提供しませんが、ユーザーアプリケーションやツールは
ファイルの内容を解釈し、必要に応じて適切な処理を行います
「普通(通常)のファイル」の特徴
・データ(情報)を保存し、読み書きする
(またはプログラム実行する) 機能を持ったもの
・ファイルタイプの指定がなく、一般的なデータファイルとして扱われる
・さまざまな形式のデータを格納できる
・データの保持と操作に使用され、ファイル自体がデータを保持する
・実行可能なコードを含むこともあり、
その場合はプログラムファイルとして実行される
「普通(通常)のファイル」である一般的な
データファイル、および、プログラムファイルの例
・テキストファイル: 文字や文字列を含む
テキストデータを格納するためのファイル形式
(.txt、.csv、.log など)
・画像ファイル: 画像データを格納するためのファイル形式
(.jpg、.png、.gif、.bmp など)
・音声ファイル: 音声データを格納するためのファイル形式
(.mp3、.wav、.aac など)
・動画ファイル: 動画データを格納するためのファイル形式
(.mp4、.avi、.mov、.mkv など)
・PDFファイル (.pdf):
ポータブルドキュメントフォーマットで記述された
文書を格納するためのファイル形式
・アーカイブファイル (.tar、.zip):
複数のファイルやディレクトリをまとめて圧縮したり、
展開したりするためのファイル形式
・データベースファイル (.db、.sqlite):
データベースの情報を格納するためのファイル形式
・実行可能ファイル: オペレーティングシステムや
プログラミング言語によって直接実行されるバイナリ形式
/bin/ の bash, netstat, mount, cat, rm, tee, ls, free などの
通常、シェルスクリプトやコマンドラインのインタープリタとして使用される
bash シェルの実行可能ファイルも、通常ファイルの扱いになってます
・スクリプトファイル: インタープリタやランタイム環境によって
実行されるテキストベースのスクリプト
(.c、.sh、.py、.js など)
/bin/ 配下の実行可能ファイルの確認例
$ ls -ld /bin/bash
-rwxr-xr-x 1 root root 1183448 Jun 19 2020 bash
$ ls -ld /bin/netstat
-rwxr-xr-x 1 root root 158288 Feb 2 2019 netstat
$ ls -ld /bin/mount
-rwsr-xr-x 1 root root 55528 Feb 7 2022 mount
$ ls -ld /bin/cat
-rwxr-xr-x 1 root root 43416 Sep 5 2019 /bin/cat
$ ls -ld /bin/rm
-rwxr-xr-x 1 root root 72056 Sep 5 2019 rm
$ ls -ld /bin/tee
-rwxr-xr-x 1 root root 43384 Sep 5 2019 tee
$ ls -ld /bin/ls
-rwxr-xr-x 1 root root 142144 Sep 5 2019 ls
$ ls -ld /bin/free
-rwxr-xr-x 1 root root 26864 Sep 9 2021 free