シェル周りを勉強した
最近自分の中でのシェルに対する興味が沸々と湧いております🔥
色々と調べておもしろかったのでまとめます。
そもそもOSとは?
オペレーティングシステム(Operating System; OS)とは
コンピュータ内の様々な複雑な動作を意識せずに、人々が容易にコンピュータを利用できるようにするソフトウェア群のことです。つまりプログラムの集合体です。
MacOSとかWindows, UNIX, LinuxなどがOSです。
例えば私たちがキーボードから入力した文字を読み込むという操作でさえ、コンピュータ内ではハードウェアの仕様にしたがって複雑な手順が踏まれます。しかし私たちはそんなことは意識せずにキーボードから入力を行えます。
OSがなければ、コンピュータをちょっと触ることでさえ専門知識が必要になっていたかもしれません
このOSに以降説明するシェルやカーネルも含まれます。
まずシェルって?
シェルはlsやcdなどのコマンドを解釈して実行する"プログラム"のこと。プログラムだったんですね
シェルの基本動作は以下の通り
- プロンプト(%などのコマンドライン上での"入力待ちだよ"と知らせる表示のこと)を表示
- ユーザからの入力があれば、入力を解析しコマンド名を切り出す
- コマンド名で指定された実行可能ファイルを実行
- 実行可能ファイルの実行が終了したら最初(1. )に戻る
※) ここで実行可能ファイルはソースプログラムをコンパイルして出来上がるファイルのことで、機械語命令の並びのことを指します。より詳細に言えば、命令列の他にコード領域の大きさやデータ領域の大きさなど、様々な情報が含まれています。
この書き方だとまるでシェルというプログラムが実行可能ファイルを実行しているように思えますが、実際は違います。
実際はシェル自体がコマンドを解釈して実行しているのではなく、システムコールをカーネルに対して行い、カーネルがこれらのコマンドの操作を実行します。
※) システムコール = 特別な関数呼び出し(ユーザが直接弄れない部分の操作を行う関数を呼ぶ)
カーネルとは?
OSの核となる部分で、コンピュータ内の低レイヤー部分に対しての操作を行います。
あらゆる操作はこのカーネルによって行われます。カーネルもプログラムです。
カーネルは低レイヤーでの複雑な処理(メモリ管理、デバイス管理など)を行ってくれます。
全体のイメージ
上図におけるApplicationがユーザが使用するアプリです。例えばコマンドラインです。
ここで、コマンドラインでは上記の説明の通り、ユーザが入力したコマンドを理解し、カーネルに実行してもらうためにシェルというプログラムが動いています。
コマンドに対する気付き
普段、Linux上でlsとかrmとか色々なコマンドを使います。何気なくこれらコマンドを叩いていますが、これってlsとかrmとかの操作が書かれた実行可能ファイルを実行しているんですねー
恥ずかしながらあんまり今まで意識してませんでした笑
Macにはbinディレクトリというものがあってそこにコマンドの実行可能ファイルが置かれている
実際に見てみると
$ ls /bin [ cp dd expr launchctl mkdir pwd sleep test bash csh df hostname link mv rm stty unlink cat dash echo kill ln pax rmdir sync wait4path chmod date ed ksh ls ps sh tcsh zsh
こんな感じでlsとかrmとか様々なコマンドの実行可能ファイルが置かれていることが確認できますね。
ファイルの種類を確認してみると
$ file ls ls: Mach-O universal binary with 2 architectures: [x86_64:Mach-O 64-bit executable x86_64] [arm64e:Mach-O 64-bit executable arm64e] ls (for architecture x86_64): Mach-O 64-bit executable x86_64 ls (for architecture arm64e): Mach-O 64-bit executable arm64e
バイナリファイルのようです。実行可能ファイルはバイナリファイルの一種でコンピュータが理解できるような形のファイルです。2進数がズラーって感じのファイル。
このfileっていうコマンド自体も/bin以外のどっかにあるfileという実行可能ファイルを実行しています。
これまでコマンドラインにコマンドを入力して、不自由なくやりたいことができているのですが、この時に「なんでコマンドの名前を打っただけで、その実行可能ファイルの場所を認識して実行できているんだ?」という疑問が湧いてきます。
これ、実際には絶対パスで指定コマンドの実行可能ファイルをしっかり確認しているんですね
環境変数 PATH
シェルは"PATH"という環境変数に入っているパス内に、コマンドとして打った実行可能ファイルがあるかを確認し、あれば実行、なければcommand not foundというエラーを吐きます。
PATHを確認してみるとmacのデフォルトでは
$ echo $PATH /user/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
というように表示されると思います。
: で複数のパスが区切られていて、「/user/local/bin」「/usr/bin」「/bin」「/usr/sbin」「/sbin」という5つパスが確認できます。
コマンドライン上でlsコマンドを打つとシェルはこの5つのパスの中にlsという実行可能ファイルがあるかを順番に探します。シェルがやってたことってこういうことだったんですね
環境変数PATHに新たにパスを付け加えるにはexportコマンドを利用して「export PATH=$PATH:通したいパス」で設定します。
しかしここでの設定はシェルが閉じてしまうと消えてしまいます。したがってシェルが開くたびに設定しなければなりません。これは面倒!!
なのでシェルが起動すると同時に毎度実行されるファイルである、.zshrcファイルにこれを書きましょう。
パスを通す とは?
command not foundエラー → シェルが指定のコマンドを見つけられていない → シェルにコマンドの実行可能ファイルの場所を伝えたい
パスを通す = シェルにコマンドを探してもらう場所を伝える = .zshrcファイル(シェル起動時に同時に実行するファイル)にexportコマンドをかく
です。
Permission Denied
パスも通してこれでコマンドを打ってみると...."""Permisson Denied"""というやつが現れることがあります。うざい!!って感じですね
Permission Deniedとは、あなたに権限がないから、実行可能ファイルが実行できないよという表示です。
なぜこんなものがあるのでしょうか?
そもそもLINUXは、サーバーでよく使われるOSですが、そのため1つのマシンへ複数のユーザーが同時にログインして操作することを前提として作られています。
この際に、秘密のファイルを他のユーザーに見られてしまったり、誤って他のユーザのファイルを上書きしてしまうことを防ぐため、アクセス権限が必要でした。
したがって一つ一つのファイルには、「誰に、どのような操作を許可するのか」という権限を規定する情報が設定されています。この情報のことを、パーミッションと呼びます。
これ以上の説明はここに託します...とてもわかりやすかったので...🙏 qiita.com
ここで言いたかったことは、
コマンド打ったらcommand not foundが出た
↓ コマンドがないか or シェルが実行可能ファイルの場所を認識できていない
whichコマンドで、そのコマンドの場所を調べる
↓(なければインストール)
.zshrcに変更加える(シェルに実行可能ファイルの位置を教えてあげる)
〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
Permission Deniedが出た
↓
実行可能ファイルのpermissionを変える
です
何か間違っていることがあったらご指摘いただけるとありがたいです🙇♂️