シェル周りを勉強した

最近自分の中でのシェルに対する興味が沸々と湧いております🔥

色々と調べておもしろかったのでまとめます。

そもそもOSとは?

オペレーティングシステム(Operating System; OS)とは

コンピュータ内の様々な複雑な動作を意識せずに、人々が容易にコンピュータを利用できるようにするソフトウェア群のことです。つまりプログラムの集合体です。

MacOSとかWindows, UNIX, LinuxなどがOSです。

例えば私たちがキーボードから入力した文字を読み込むという操作でさえ、コンピュータ内ではハードウェアの仕様にしたがって複雑な手順が踏まれます。しかし私たちはそんなことは意識せずにキーボードから入力を行えます。

OSがなければ、コンピュータをちょっと触ることでさえ専門知識が必要になっていたかもしれません

このOSに以降説明するシェルやカーネルも含まれます。

まずシェルって?

シェルはlsやcdなどのコマンドを解釈して実行する"プログラム"のこと。プログラムだったんですね

シェルの基本動作は以下の通り

  1. プロンプト(%などのコマンドライン上での"入力待ちだよ"と知らせる表示のこと)を表示
  2. ユーザからの入力があれば、入力を解析しコマンド名を切り出す
  3. コマンド名で指定された実行可能ファイルを実行
  4. 実行可能ファイルの実行が終了したら最初(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を変える

です

何か間違っていることがあったらご指摘いただけるとありがたいです🙇‍♂️