はじめに
この度、訳あってCLIツールをつくろうと思ったのですが、そもそもコマンドって何? と思ったので簡単に調べてみました。
普段シェル(私の場合は bash なので以下 bash を想定して話しています)に対して pwd
とか ls
とか、はたまた自分で入れた git
とか aws
とかコマンドを入力して操作しているわけですが、これはつまり何をしているのか? ということについてごく簡単に調べてみました。
コマンドを実行するということ
まず、
コマンドを実行するということは、その処理内容が書かれた実行ファイルを実行するということ。
コマンドを入力するということは、実行する実行ファイル名を入力するということ。(コマンド = 実行ファイル名)
シェルにコマンドを入力して実行する方法とその際の挙動
コマンドを実行したいとき、入力方法は下記2パターンあります。
-
スラッシュ付きで実行ファイルの格納場所も含めて実行ファイル名を入力する方法。
→ 指定されたその実行ファイルを実行する
$ /bin/ls
-
**単にコマンドを入力する方法。**日常的にはこちら。
→ 環境変数$PATHに書いてあるディレクトリの中からそのコマンドの実行ファイルを検索し、最初に見つかったものを実行する
(より左に書いてあるディレクトリから順に検索していく)
( "PATHが通ってなくて実行できない" というのはこういうことだったんですね)
$ ls
結局のところコマンドを実行するということは、実行ファイルを特定してそれを実行する、ということなんですね。
ここでちなみに、
実行ファイルというのは、C言語などで書かれたプログラムを機械語にコンパイルしてビルドされたバイナリファイルのこと。
その環境(OSやアーキテクチャ)に合わせてビルドされたバイナリファイルしか実行できない。(例:darwin の amd64 など)
おまけ
ここまで調べて湧いてきた疑問
- シェルに入力したものはすべてコマンドとして受け取られるということ?
- ではシェルスクリプトを実行するときのあれは? コマンドとして受け取られてるってこと?
- 入力したものはコマンドとして受け取られるとしたら、バイナリファイルとシェルスクリプトでは中身がぜんぜん違うのになぜそれぞれ適切に実行できるの?
ということで、コマンドの実行方法と比較して、シェルスクリプトの実行方法を確認しておきます。
シェルスクリプトを実行するということ
実験でシェルスクリプトを実行しようとした際、実行権限がないと怒られたので、必要に応じて chmod +x sample.sh
などします。
シェルスクリプトの実行方法
-
bashコマンドの引数として指定する。
カレントディレクトリにファイルがある場合は下記で実行できる。ない場合でも場所指定すれば実行できる。
$ bash sample.sh
$ bash ../sample.sh
- **コマンドと同様な扱いをする その1:スラッシュ付きで場所も指定して入力する。**日常的にはこれ。
$ ./sample.sh
-
コマンドと同様な扱いをする その2:環境変数$PATHに書いてあるディレクトリにシェルスクリプトを置いて、シェルスクリプト名を入力する。
/usr/local/bin/ に sample.sh を置いて、ファイル名のみ入力する
$ sample.sh
ちなみに、
Windowsと違い、MacやLinuxでは拡張子という概念がないので、ファイル名に .sh が付いていたらシェルスクリプトというわけではない。.sh は人間が識別しやすいように習慣的に付けているだけ。samplesh というファイル名でも中身がシェルスクリプトならシェルスクリプト。
シェルスクリプトの中身の1行目にはShebang(例:#!/bin/bash
)を書くが、これは実行するときに使用するインタプリタを指定しているだけで、なくてもシェルスクリプトとして動く。
疑問に対する解:
→ bashのマニュアルの書いてありました
(日本語版:https://linuxjm.osdn.jp/html/GNU_bash/man1/bash.1.html の"コマンドの実行"の項)
最初はコマンドと同じようにその名前の実行ファイルを探すが、
このファイルが実行可能フォーマットでないために実行が失敗し、 かつディレクトリでもない場合には、 このファイルは シェルスクリプト(shell script)であるとみなされます。
要するに、基本的にはコマンドであると仮定して処理するけど、コマンドではないとわかると次はシェルスクリプトとして処理するってことですね。
終わりに
マニュアル(公式ドキュメント)を読むって大事ですね。
コマンドはプログラムから生まれ出てきたもので、シェルスクリプトはそのコマンド群の並べることで成り立っている、という違いがわかりました。
プログラムを書くときとシェルスクリプトを書くときは別の思考回路を持て、というのはこういう違いからくるものなんですね。
参考:https://shellscript.sunone.me/tutorial.html
今回ごく初歩的な内容で厳密性に欠けるところも多々あるかと思います。間違いや同時に知っておくとよいポイント等含め、お気づきの際はコメントいただけたら幸いです。