このページで解説している内容は、以下の YouTube 動画の解説で見ることができます。

Linuxコマンドの基本:シェルスクリプトの配置

シェルスクリプトの配置

 シェルスクリプトを作成して実行する際、これまでの例では常にファイル名の先頭に ./ を付けて実行してきました。しかし、./ を付けずにシェルスクリプトを実行しようとすると、どうなるのでしょうか。ここでは、シェルスクリプトの配置と実行方法について詳しく解説します。

./ を付けずに実行するとエラーになる理由

まず、以下のようなシェルスクリプトを作成してみましょう。

ステップ1:シェルスクリプトの作成

user01@ubuntu:~$ nano disksize.sh

disksize.sh の内容

#!/bin/bash
du -h ~ | tail -n 1

解説

  • #!/bin/bash:シェルスクリプトが bash シェルで実行されることを指定しています。
  • du -h ~ | tail -n 1:ホームディレクトリのディスク使用量を表示するコマンドです。

ステップ2:実行権限の付与

作成したシェルスクリプトに実行権限を与えます。

user01@ubuntu:~$ chmod +x disksize.sh

解説

  • chmod +x disksize.shdisksize.sh に実行権限を付与します。

ステップ3:./ を付けずに実行

それでは、./ を付けずにシェルスクリプトを実行してみます。

user01@ubuntu:~$ disksize.sh

出力結果

disksize.sh: コマンドが見つかりません

解説

  • シェルスクリプトを実行しようとしましたが、「コマンドが見つかりません」というエラーが表示されました。
  • これは、シェルが disksize.sh という名前のコマンドを探しましたが、見つけることができなかったためです。

シェルのサーチパスとコマンドの探索

 シェルがコマンドを実行する際には、サーチパスと呼ばれる一連のディレクトリを検索して、指定されたコマンドを探します。サーチパスは環境変数 PATH によって定義されています。

サーチパスの確認

echo コマンドを使って、現在のサーチパスを確認してみましょう。

user01@ubuntu:~$ echo $PATH

出力結果

/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games

解説

  • PATH には、コマンドを検索するディレクトリの一覧がコロン(:)で区切られて格納されています。
  • 上記の出力から、シェルは以下のディレクトリを順番に検索します。

/usr/local/sbin → /usr/local/bin → /usr/sbin → /usr/bin → /sbin → /bin → /usr/games → /usr/local/games

重要なポイント

  サーチパスにはカレントディレクトリ(./)やホームディレクトリ(/home/user01)は含まれていません。

コマンドが見つからない理由

  • シェルはサーチパス内のディレクトリを順に検索して disksize.sh という名前のファイルを探します。
  • しかし、disksize.sh はカレントディレクトリ(/home/user01)に存在しており、サーチパスには含まれていないため、シェルはこのファイルを見つけることができません。
  • その結果、「コマンドが見つかりません」というエラーが表示されます。

相対パス・絶対パスを使った実行

 サーチパスに含まれていない場所にあるシェルスクリプトを実行するには、相対パスまたは絶対パスでファイルを指定する必要があります。

相対パスでの実行(./ を付ける)

 これまでの例では、カレントディレクトリにあるシェルスクリプトを実行する際に、./ を付けて相対パスを指定していました。

user01@ubuntu:~$ ./disksize.sh

出力結果

18M    /home/user01

解説

  • ./disksize.sh とすることで、カレントディレクトリ(./)にある disksize.sh を指定しています。
  • これにより、シェルは disksize.sh を実行することができます。

絶対パスでの実行

シェルスクリプトの絶対パスを指定して実行することも可能です。

user01@ubuntu:~$ /home/user01/disksize.sh

出力結果

18M    /home/user01

解説

  • シェルスクリプトの完全なパス(/home/user01/disksize.sh)を指定しています。
  • これにより、シェルは指定された場所から直接シェルスクリプトを実行します。

./ を付ける理由

  • カレントディレクトリにあるシェルスクリプトを手軽に実行するためには、./ を付けて相対パスを指定するのが便利です。
  • 毎回長い絶対パスを入力するのは手間がかかるため、./ を使うことで入力を簡略化できます。

サーチパスにカレントディレクトリが含まれていない理由

セキュリティ上の考慮

  • カレントディレクトリ(./)をサーチパスに含めないのは、セキュリティ上の理由からです。
  • サーチパスにカレントディレクトリを含めると、予期せぬコマンドが実行されるリスクがあります。

具体的な例

 システム管理者が /tmp ディレクトリで作業しているときに、悪意のあるユーザーがコマンドと同名のスクリプトを配置しておくと、不正なスクリプトが実行されてしまう可能性があります。

解説

 システム管理者が /tmp ディレクトリで作業中に、悪意のあるユーザーがコマンドと同名のスクリプトを配置すると、意図せず不正なスクリプトが実行される危険性があります。これは「パス・ハイジャック攻撃」や「パスの悪用」とも呼ばれる脅威です。

 この問題は、システム管理者がカレントディレクトリ(例:/tmp)にいる場合や、環境変数 PATH にカレントディレクトリ (.) が含まれている場合に発生しやすくなります。

なぜ不正なスクリプトが実行されるのか
  1. カレントディレクトリ優先の検索
     シェルはコマンドを実行する際、PATH 環境変数に従ってコマンドの場所を探します。PATH にカレントディレクトリ (.) が含まれている場合、カレントディレクトリにあるファイルが優先して検索されるため、同名のファイルがあればそれを実行してしまう可能性があります。
  2. 悪意あるユーザーによるスクリプト配置
     /tmp ディレクトリは全ユーザーが書き込み可能な場所なので、悪意のあるユーザーが任意のスクリプトを配置することが可能です。もしそのスクリプトがシステム管理者が実行するコマンドと同じ名前であれば、システム管理者が意図せずにそのスクリプトを実行してしまうリスクがあります。
  3. システム管理者の権限で実行される
     システム管理者が不正なスクリプトを実行してしまうと、システム管理者の権限でそのスクリプトが動作します。そのため、重要なシステム設定の変更や機密情報の盗難、悪意のある操作が実行される可能性が生じます。

ベストプラクティス

 そのため、カレントディレクトリをサーチパスに含めず、実行したいファイルがある場合は明示的にパスを指定することが推奨されています。

不要なファイルの削除

作業が終わったら、作成したスクリプトを削除します。

user01@ubuntu:~$ rm disksize.sh 

まとめ

  • シェルはコマンドを実行する際に、環境変数 PATH に設定されたサーチパスを順番に検索します。
  • サーチパスにはカレントディレクトリ(./)は含まれていないため、ファイル名だけでカレントディレクトリ内のシェルスクリプトを実行することはできません。
  • カレントディレクトリ内のシェルスクリプトを実行する場合は、相対パス(./disksize.sh)や絶対パス(/home/user01/disksize.sh)を指定する必要があります。
  • カレントディレクトリをサーチパスに含めないのは、セキュリティ上の理由からであり、予期しないコマンドの実行を防ぐためです。

 これらの理由から、シェルスクリプトを実行する際には、./ を付けて相対パスで指定する方法が一般的であり、安全性も高いといえます。