サーバ管理者のためのプログラミング入門(シェルプログラミング基礎8~条件分岐その4) [サーバ管理者のプログラミング]
testコマンドは、これまで説明した数値の大小比較や文字列の比較の他に、ユニークな機能を持っている。それは、ファイル等の形式やパーミッションを判定するという機能である。これは地味に便利なのでサーバ管理者であれば知っていると多いに活用できる機能だ。
1.ファイル等の形式を判定する機能
まずは、ファイル等の形式を判定する機能から紹介する。「等」と強調しているのは、ファイル以外にもディレクトリやシンボリックリンク、スペシャルファイル、パイプ、ソケットなど何でもござれだから。ただ、よく使うのは以下の3つだろうか?
-f ファイル名 : 「ファイル名」に記述されたファイルが存在し、かつそのファイルが通常のファイルであれば真
-d ディレクトリ名 : 「ディレクトリ名」に記述されたディレクトリが存在し、かつそれがディレクトリであれば真
-L ファイル名 : 「ファイル名」に記述されたファイルが存在し、かつそのファイルがシンボリックリンクであれば真
他にもあるが、あまり使わないと思うので説明は割愛している。
まず、-fとか-dとか-Lとかのオプションの後ろに指定する名前のファイル(やディレクトリやシンボリックリンク)が存在しない場合は、そもそも「偽」という判定が返ってくる。
このようなディレクトリで「unknown」という名前を指定してtestコマンドを実行してみよう。
「unknown」という名前のファイルもディレクトリもシンボリックリンクも存在しないので、どれも実行結果が0でない(=「偽」)。
「file」というファイルについて同様に実行してみると…
「file」という名前の通常のファイルは存在する。よって、-fオプションの判定結果だけ実行結果が0(=「真」)に、それ以外は0でない(=「偽」)。
同様に、「directory」について実行してみよう。
と、このようにディレクトリもちゃんと判定されている。
シンボリックリンクも同様の結果が得られることを確認しておこう。
おや!?と思うだろう。-dが偽で、-Lが真になるのは判る。しかし-fも真になっている。実は、ヒントがすでに示されていて…
これは、そのシンボリックリンクが指し示している先がファイルだからこういう結果になっているのであった。
だから、ディレクトリに対してシンボリックリンクを張ると実行結果も変わってくる。
と、ディレクトリに対するシンボリックリンクを作成し、これを判定してみると…
-Lオプションと-dオプションの判定結果が「真」に、-fオプションの判定結果が「偽」に変化した。
2.ファイルなどのパーミッションを判定する機能
続いて、ファイルなどのパーミッションを判定する機能を紹介する。
いくつか判定オプションが存在するが、その中でも比較的よく使うであろうオプションのみ紹介する。
-r ファイル名 : 「ファイル名」に指定されたファイル等が存在し、かつ読み取りが許可されていれば真
-w ファイル名 : 「ファイル名」に指定されたファイル等が存在し、かつ書き込みが許可されていれば真
-x ファイル名 : 「ファイル名」に指定されたファイル等が存在し、かつ実行可能(ディレクトリの場合は進入可能)であれば真
なお、これらのオプションはパーミッションを判定するのであってファイルの中には直接触らないので、読み取り権限がないファイル等でもエラーになったりしない。
では、試してみよう。以下のようなファイルやディレクトリを準備した。
ファイルやディレクトリのオーナーはrootである。判りやすいようにディレクトリ名・ファイル名にパーミッションを数値化してつけて有る。
これを、「piro791」アカウントから判定するとどうなるだろうか。
このようなアカウントである。
ファイルの読み取り権限についてチェックしてみる。事前の予想では、directory777、file444、file666、file777が真で、directory700とfile400が偽になるはずである。
事前の予想通りの結果になった。特にエラーにもならず綺麗に判定されていることがわかる。
では、「-w」オプションも試してみよう。すると…
file444には読み取り権限こそあるものの、書き込みの権限は無いので、ここが「偽」となった。
続いて「-x」も試してみよう。
directory777にはcdコマンドで進入できるし、file777はバイナリーファイルかスクリプトファイルかは判らないが実行できる権限が付いていることが確認できる。
では、ちょっとおかしなパーミッションを設定したファイルを用意してみた。
ファイルのオーナーはrootで、これをpiro791アカウントで扱うとなると、読めない・書けない・実行できるという謎の状態になっている。(笑)
testコマンドを試してみよう。
こんなおかしなファイルでもちゃんとパーミッションの判定はできるのであった。
1.ファイル等の形式を判定する機能
まずは、ファイル等の形式を判定する機能から紹介する。「等」と強調しているのは、ファイル以外にもディレクトリやシンボリックリンク、スペシャルファイル、パイプ、ソケットなど何でもござれだから。ただ、よく使うのは以下の3つだろうか?
-f ファイル名 : 「ファイル名」に記述されたファイルが存在し、かつそのファイルが通常のファイルであれば真
-d ディレクトリ名 : 「ディレクトリ名」に記述されたディレクトリが存在し、かつそれがディレクトリであれば真
-L ファイル名 : 「ファイル名」に記述されたファイルが存在し、かつそのファイルがシンボリックリンクであれば真
他にもあるが、あまり使わないと思うので説明は割愛している。
まず、-fとか-dとか-Lとかのオプションの後ろに指定する名前のファイル(やディレクトリやシンボリックリンク)が存在しない場合は、そもそも「偽」という判定が返ってくる。
[root@kagami tmp]# ls -la 合計 24 drwxrwxrwt 4 root root 4096 3月 8 17:35 . drwxr-xr-x 22 root root 4096 3月 8 13:59 .. drwxrwxrwt 2 root root 4096 3月 8 13:59 .ICE-unix drwxr-xr-x 2 root root 4096 3月 8 17:34 directory -rw-r--r-- 1 root root 0 3月 8 17:34 file lrwxrwxrwx 1 root root 4 3月 8 17:35 sym-link -> file
このようなディレクトリで「unknown」という名前を指定してtestコマンドを実行してみよう。
[root@kagami tmp]# test -f unknown [root@kagami tmp]# echo $? 1 [root@kagami tmp]# test -d unknown [root@kagami tmp]# echo $? 1 [root@kagami tmp]# test -L unknown [root@kagami tmp]# echo $? 1
「unknown」という名前のファイルもディレクトリもシンボリックリンクも存在しないので、どれも実行結果が0でない(=「偽」)。
「file」というファイルについて同様に実行してみると…
[root@kagami tmp]# test -f file [root@kagami tmp]# echo $? 0 [root@kagami tmp]# test -d file [root@kagami tmp]# echo $? 1 [root@kagami tmp]# test -L file [root@kagami tmp]# echo $? 1
「file」という名前の通常のファイルは存在する。よって、-fオプションの判定結果だけ実行結果が0(=「真」)に、それ以外は0でない(=「偽」)。
同様に、「directory」について実行してみよう。
[root@kagami tmp]# test -f directory [root@kagami tmp]# echo $? 1 [root@kagami tmp]# test -d directory [root@kagami tmp]# echo $? 0 [root@kagami tmp]# test -L directory [root@kagami tmp]# echo $? 1
と、このようにディレクトリもちゃんと判定されている。
シンボリックリンクも同様の結果が得られることを確認しておこう。
[root@kagami tmp]# test -f sym-link [root@kagami tmp]# echo $? 0 [root@kagami tmp]# test -d sym-link [root@kagami tmp]# echo $? 1 [root@kagami tmp]# test -L sym-link [root@kagami tmp]# echo $? 0
おや!?と思うだろう。-dが偽で、-Lが真になるのは判る。しかし-fも真になっている。実は、ヒントがすでに示されていて…
-rw-r--r-- 1 root root 0 3月 8 17:34 file lrwxrwxrwx 1 root root 4 3月 8 17:35 sym-link -> file
これは、そのシンボリックリンクが指し示している先がファイルだからこういう結果になっているのであった。
だから、ディレクトリに対してシンボリックリンクを張ると実行結果も変わってくる。
[root@kagami tmp]# ln -s directory sym-link2 [root@kagami tmp]# ls -la 合計 24 drwxr-xr-x 2 root root 4096 3月 8 17:34 directory lrwxrwxrwx 1 root root 9 3月 8 17:44 sym-link2 -> directory
と、ディレクトリに対するシンボリックリンクを作成し、これを判定してみると…
[root@kagami tmp]# test -f sym-link2 [root@kagami tmp]# echo $? 1 [root@kagami tmp]# test -d sym-link2 [root@kagami tmp]# echo $? 0 [root@kagami tmp]# test -L sym-link2 [root@kagami tmp]# echo $? 0
-Lオプションと-dオプションの判定結果が「真」に、-fオプションの判定結果が「偽」に変化した。
2.ファイルなどのパーミッションを判定する機能
続いて、ファイルなどのパーミッションを判定する機能を紹介する。
いくつか判定オプションが存在するが、その中でも比較的よく使うであろうオプションのみ紹介する。
-r ファイル名 : 「ファイル名」に指定されたファイル等が存在し、かつ読み取りが許可されていれば真
-w ファイル名 : 「ファイル名」に指定されたファイル等が存在し、かつ書き込みが許可されていれば真
-x ファイル名 : 「ファイル名」に指定されたファイル等が存在し、かつ実行可能(ディレクトリの場合は進入可能)であれば真
なお、これらのオプションはパーミッションを判定するのであってファイルの中には直接触らないので、読み取り権限がないファイル等でもエラーになったりしない。
では、試してみよう。以下のようなファイルやディレクトリを準備した。
[piro791@kagami tmp]$ ls -la drwx------ 2 root root 4096 3月 8 17:59 directory700 drwxrwxrwx 2 root root 4096 3月 8 17:59 directory777 -r-------- 1 root root 0 3月 8 17:55 file400 -r--r--r-- 1 root root 0 3月 8 17:55 file444 -rw-rw-rw- 1 root root 0 3月 8 17:55 file666 -rwxrwxrwx 1 root root 0 3月 8 17:55 file777
ファイルやディレクトリのオーナーはrootである。判りやすいようにディレクトリ名・ファイル名にパーミッションを数値化してつけて有る。
これを、「piro791」アカウントから判定するとどうなるだろうか。
[piro791@kagami tmp]$ id uid=500(piro791) gid=500(piro791) 所属グループ=500(piro791)
このようなアカウントである。
ファイルの読み取り権限についてチェックしてみる。事前の予想では、directory777、file444、file666、file777が真で、directory700とfile400が偽になるはずである。
[piro791@kagami tmp]$ test -r directory700;echo $? 1 [piro791@kagami tmp]$ test -r directory777;echo $? 0 [piro791@kagami tmp]$ test -r file400;echo $? 1 [piro791@kagami tmp]$ test -r file444;echo $? 0 [piro791@kagami tmp]$ test -r file666;echo $? 0 [piro791@kagami tmp]$ test -r file777;echo $? 0
事前の予想通りの結果になった。特にエラーにもならず綺麗に判定されていることがわかる。
では、「-w」オプションも試してみよう。すると…
[piro791@kagami tmp]$ test -w directory700;echo $? 1 [piro791@kagami tmp]$ test -w directory777;echo $? 0 [piro791@kagami tmp]$ test -w file400;echo $? 1 [piro791@kagami tmp]$ test -w file444;echo $? 1 [piro791@kagami tmp]$ test -w file666;echo $? 0 [piro791@kagami tmp]$ test -w file777;echo $? 0
file444には読み取り権限こそあるものの、書き込みの権限は無いので、ここが「偽」となった。
続いて「-x」も試してみよう。
[piro791@kagami tmp]$ test -x directory700;echo $? 1 [piro791@kagami tmp]$ test -x directory777;echo $? 0 [piro791@kagami tmp]$ test -x file400;echo $? 1 [piro791@kagami tmp]$ test -x file444;echo $? 1 [piro791@kagami tmp]$ test -x file666;echo $? 1 [piro791@kagami tmp]$ test -x file777;echo $? 0
directory777にはcdコマンドで進入できるし、file777はバイナリーファイルかスクリプトファイルかは判らないが実行できる権限が付いていることが確認できる。
では、ちょっとおかしなパーミッションを設定したファイルを用意してみた。
[piro791@kagami tmp]$ ls -l file771 -rwxrwx--x 1 root root 0 3月 8 18:15 file771
ファイルのオーナーはrootで、これをpiro791アカウントで扱うとなると、読めない・書けない・実行できるという謎の状態になっている。(笑)
testコマンドを試してみよう。
[piro791@kagami tmp]$ test -r file771;echo $? 1 [piro791@kagami tmp]$ test -w file771;echo $? 1 [piro791@kagami tmp]$ test -x file771;echo $? 0
こんなおかしなファイルでもちゃんとパーミッションの判定はできるのであった。
コメント 0