i-Vinci TechBlog
株式会社i-Vinciの技術ブログ

Linux操作の足掛かり

こんにちは。
最近は雨不足で野菜が値上がりしないか戦々恐々のakiyoshiです。特に私の夏の楽しみであるトマト、ナス、ピーマンが値上がらないことを願っています。

ここから本題
今回は初めてのLinuxでひっかかりそうなところを残してみます。
というのも、未経験入社の方との会話で開発環境周り(Linux)の話になった途端「なるほど分からん」となって困ったため。
会話してて思うのですが、独学でEclipseやVS Code上でコーディングは行っていても、環境周りまではなかなか手が回らないんですよね。
いざ「テストするので、サーバー環境の準備手伝ってください」と言われ、あたふたとしてしまう事態は避けないといけないですし、そもそも言葉が通じないのはさすがに辛いというところで。

OSの系統図

かなり省略していますが、よく知るOSは以下のような括りとなっています。

OS系統

主題のLinuxはUnixとで系統を分けていますが、血のつながりがない親戚なんて言われたりして、実態はかなり近しいです。
そのあたりの経緯はLinuxの起源を調べるといくらでも出てくるため、興味があれば調べてみてください。
※流れできちんとしたUnixやLinuxの系図も出てくると思います。

以降、Linuxと書いているところはUnixでも同じです。

よく知るOSの特徴

  • Windows
    • 圧倒的シェア(PCとして)
    • GUIが優秀
  • Mac
    • 何気にUnix系統
    • ハードウェアとの一体感
    • GUIが優秀
  • Linux
    • 安価
    • 自由度が高い
    • 安定性が高い
    • CUIがメイン

ディレクトリ(フォルダ)構成

正直、日頃触ったことがない人にとって、Linux系が良く分からない要因のひとつと思います。
結局はOSや利用者次第のため、完璧に覚える必要はありませんが
ディレクトリの大雑把な用途があることは知っておく必要はあります。
残念ながら、Cドライブ直下のProgram Filesなんてものはない。

ディレクトリ読み説明
/ルート最上位に位置する
├─ binbinary全ユーザーが利用する基本的なプログラム群を管理する
├─ bootbootシステム起動に必要なファイルを管理する
├─ devdeviceデバイスファイル群を管理する
│ └ cpu
├─ etcetceteraLinux設定ファイルなどを管理する
│ └ opt
├─ homehome一般ユーザーのホームディレクトリ。配下にユーザー毎のディレクトリが生成される。
│ └ vagrant※分かりづらいですが、ユーザー名(vagrant)です
├─ liblibraryプログラムに必要な各種ライブラリ群を管理する
├─ mediamediaシステムが外部装置 (USB や CD-ROM など) のマウンティングパスとして利用する
├─ mntmountユーザーが一時的なマウンティングパスとして利用する
├─ optoptionアプリケーションパッケージのインストール先として利用する
├─ procprocess実行中のプロセス情報などを格納する
├─ rootrootrootユーザーのホームディレクトリ
├─ sbinsystem binaryシステム管理用のコマンドやプログラムを管理する
├─ syssystemカーネルやシステム情報を管理する
├─ tmptemporary全システム、ユーザーが利用する一時保存用ディレクトリ
├─ usruser各ユーザーが共通して利用するプログラムやライブラリなどを管理する
│ ├─ bin
│ ├─ include
│ ├─ lib
│ ├─ local
│ ├─ sbin
│ ├─ share
│ └ src
└ varvariableログを始めとした動的に変更が入るファイル群を管理する
  ├─ log
  └ mail

パスについて

パスの表現の仕方として、絶対パスと相対パスがあります。

  • 絶対パス
    • ルートディレクトリから指定ファイルまで経由する全てのディレクトリを記載する
    • イメージ的にはファイルの住所を書く
      例)東京都千代田区神田錦町3丁目12-10竹尾ビル8Fのヴィンチさん
    • カレントディレクトリがどこにいようとも必ず同じ結果になる
    • 毎回使うには記載が冗長
  • 相対パス
    • カレントディレクトリから指定ファイルまで経由するディレクトリを記載する
    • イメージ的には現在地からの道のりを書く
      例)現在地から少し戻って、右折した竹尾ビル8Fのヴィンチさん
    • カレントディレクトリが変わると、必然的に相対パスの指定先も異なります。

絶対パスを使うと、『間違いなく到達できるから便利だな』と思うかもしれませんが、開発をしていると相対パスのほうがよく使います。両方、理解しておきましょう。

たとえば、以下のディレクトリ構成のアプリケーションがあったとして、
complete.htmlからstyles.cssを読み込みたいとき、
相対パスだと常に../public/css/style.cssで読み込むことができます。
しかし、絶対パスの場合だと、

  • /usr/local配下に設置時は/usr/local/app/public/css/style.css
  • /home/vagrant/develop配下に設置時は/home/vagrant/develop/app/public/css/style.css

という具合にappディレクトリをどこに設置するかで読み込み先の指定が変化してしまいます。
『初期開発の段階からすでに本番サーバーの環境が完全に決まっていて、ローカルでもそれが完全に再現できる。』のであれば、絶対パスだけで開発してもいいんじゃないでしょうか(あるんだろうか。そんなこと)

.
└── app
    ├── app.rb
    ├── public # cssやjsはここ
    │   └── css
    │       └── styles.css
    └── views # ビューファイルはここ
        ├── complete.html
        ├── confirm.html
        └── input_form.html

おまけ

表記意味
/ルート(最上位)ディレクトリ
../上位ディレクトリ
./カレントディレクトリ(現在地)
~/ホームディレクトリ
.ファイル名隠しファイル

カーネルとシェルとターミナル

LinuxはCUIで動かすことが多いため、そのあたりについて簡単に触れていきます。
ターミナルイメージ
※キャプチャはWindowsコマンドプロンプト(cmd.exe)

動かす場合のざっくりとした流れは、

  1. ユーザーがターミナルにコマンドを打ち込み、
  2. それをシェルが翻訳して
  3. カーネル(=OSのコア)が命令を実行し、結果をシェルに渡す
  4. シェルは結果をユーザーがわかる形に翻訳し
  5. ターミナルがそれを表示している。

雑なイメージとしては

  • ターミナルはテキストエディタ
  • シェルがプログラミング言語
    という具合で考えておけば良いです。

限度はありますが、ユーザーはターミナルやシェルを割と好きに選ぶことができます。

シェルとカーネル
引用元:シェルの概念と機能

シェルの種類

先ほど述べたように、ざっくりシェルとはプログラミング言語です。
そのため、使うシェルを設定で変更したり、使いたいシェルが手元にない場合はインストールすることも可能です。
また、OSに依ってデフォルトで利用できるシェルは異なりますが、
WindowsでもLinux系のシェルは利用可能だったりします。(※Git Bash、WSLのBash)

試しに手元のLinuxサーバーを確認してみると、デフォルトシェルはbash(/bin/shにシンボリックリンクが張られているため)でした。

# 現在利用中のシェルを確認
$ echo $SHELL
> /bin/sh
$ ls -la /bin/sh
lrwxrwxrwx. 1 root root 4 Apr  3 05:22 /bin/sh -> bash

シェル系統

シェルのコマンドについて

CUIでコンピュータを操作しようとすると、コマンド(命令)を打つ必要があります。(マウスでカチカチできないので。)
その際、基本的なコマンドの書き方は{コマンド} {オプション} {引数}の形となっています。

# 指定したディレクトリ(引数)配下のファイル情報を標準出力する(コマンド)※一覧形式で(オプション)
$ ls -l /usr/local/bin

そもそも、コマンドには何を指定するのかというと「実行ファイル」を指定します。
『ls, cdはファイルではないんじゃ・・・?』と思ったら、しっかり実行ファイルになってます。

$ which cd
/bin/cd
# 実行権限(x)がついている
$ ls -la /bin/cd
-rwxr-xr-x. 1 root root 26 Nov 24  2021 /bin/cd
$ od /bin/cd 
> 0000000 020443 061057 067151 071457 005150 072542 066151 064564
  0000020 020156 062143 021040 040044 005042
  0000032

ユーザーがcd /homeとした場合、

  1. $PATH(例えば /sbin:/bin:/usr/sbin:/usr/bin)を見て
  2. cdの実行ファイルの場所を探し、
  3. ファイル(/bin/cd)を実行

という流れになります。

コマンド部の実行ファイル指定について

コマンドについて話をしたところで、次にスクリプトを動かしてみます。
今回は以下の簡単な物を用意します。

/home/vagrant/test.sh

#! /bin/bash

echo $0 # 実行ファイルを標準出力する

実際に実行してみます。

# カレントディレクトリを確認
$ pwd
> /home/vagrant
# 実行不可
$ test.sh
> -bash: test.sh: command not found
# 実行可(実行権限が必要)
$ ./test.sh
> /home/vagrant/test.sh

上記のようにtest.shだけでは実行ができません。
コマンド部に入力された「test.sh」だけだと、PATHが通っているディレクトリ内を探しに行き、そこに存在しない場合は「見つからなかった」と実行を諦めます。(※おそらく意図せぬファイルの実行を防止するため)
ですので、実行ファイルは明示的に「このファイル!」と指定してやる必要があります。
指定の方法は$ ./test.sh$ /home/vagrant/test.shのように相対パス、絶対パスでも良いですし、
PATHが通っている所にファイルを設置したうえでtest.shとしても問題ありません。
ローカル開発環境である場合は自分の作業ディレクトリにPATHを通すのもありだと思います。

# PATHが通っているディレクトリに設置
$ echo $PATH
> /usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin
$ ls -l /usr/local/bin/test.sh
> -rwxrwxr-x. 1 vagrant vagrant 28 Jul 16 07:47 /usr/local/bin/test.sh

# 作業ディレクトリでパス記載なしファイル名のみで実行
$ pwd
> /home/vagrant
$ test.sh
> /usr/local/bin/test.sh

実行結果から、カレントディレクトリではなく、PATHが通っているディレクトリのファイルが実行されたことが分かります。

まとめ

今回は理解しやすさを重視したため、
全てを説明していません(というよりできません)し、厳密に正しいかと言われると違うと思います。
ただ、今回の内容が初学者の取っ掛かりとして役に立てば、幸いと思います。
長々と書きましたが、結局は適当に環境を作って壊しを繰り返すのが一番早い気がしますけどね。(壊すのは仮想環境でやってください)

何よりも優先してコマンドを覚えるのに必死になりがちな方へ

$ help
$ man man

参考