IT・WEB・ゲーム業界の転職に強いR-Stone

転職コラム

Linuxの「Shell」とは?Shellの種類やできることなどをわかりやすく解説

Linuxの「Shell」とは?Shellの種類やできることなどをわかりやすく解説

Linuxサーバーの管理に興味がありますか?サーバーの操作にはシェルの操作やシェルスクリプトの作成は欠かせません。

Shellは貝殻ではありませんが、Linux系OSの中核(カーネル)から見るとShellの名前にふさわしい役割を持っています。

シェルとシェルスクリプトの違いや、いろいろなシェルの種類、シェルの基本コマンドの使い方、スクリプトの作成方法も分かりやすく解説します。

Linuxのシェル(Shell)とは?

Linuxで管理的な操作をおこなう際にはシェル(Shell)と呼ばれるプログラムがオペーレーターとOSとの間に介在します。シェルの基本を詳しく見ていきましょう。

シェルの定義

シェルは、オペーレーターが入力した文字やファイルに記載されたテキストを解釈して、OSに伝え、逆にOSからの応答も文字として提示するプログラムの総称です。LinuxをはじめとするサーバーOSではシェルなどテキストベースの方式がよく使われます。

WindowsやmacOSではグラフィカルユーザーインターフェース(GUI)を標準としておりマウスを使いアイコンなどをクリックしてOSやアプリケーションを操作しますが、シェルは文字を使ってやりとりをするのが特徴です。

Linux系のOSで起動時に最初に読み込まれるのがカーネルです。カーネルはメモリやCPU、キーボードなど基本的なハードウェアを制御するOSの中核部分です。カーネルが起動したあと、ユーザーからの操作を受け付ける窓口となるのがシェルです。

シェル(Shell)は、英語の辞書を引くと、動植物の外部を覆う堅い部分などの意味ですが、中核となるOSのカーネルを包み込む包装紙や皮にあたるのがシェルであり、OSの中核とユーザーとの仲介をするソフトウェアです。

例えば、ラーメン店の厨房をカーネルに見立てると、注文を聞きに来る従業員がシェルに相当します。従業員は厨房に客の注文内容を伝えます。厨房では注文に応じて鍋やコンロなどのハードウエアを使い麺やスープなどが調理され、できあがった料理を従業員が目の前まで運んできてくれます。

シェルスクリプトとの関係性

シェルとシェルスクリプトは混同しがちですが、シェルはテキスト情報を解釈してOSとの仲介をしてくれるソフトウェアであり、シェルスクリプトはシェルに入力する一連のテキストを記録したファイルです。つまり、シェルはソフトウェアで、シェルスクリプトはテキストファイルです。

Linuxはさまざまな用途で使用できますが、サーバー用途の場合、例えば定期的にファイルをバックアップしたり不要なファイルを削除するなどの作業があります。

もちろん毎回シェルにキーボードからコマンドを入力してもよいですが、複数のコマンドを1文字も間違えずに、しかも深夜に実施するとなるとシェルスクリプトの出番です。

キーボードから入力するのが5つのコマンドだとすれば、単純にテキストの1行目に1つめのコマンド、テキストの2行目に2つめのコマンド、のように5行のテキストをファイルに保存すればシンプルなシェルスクリプトのできあがりです。

例えば、バックアップの場合は以下の内容をファイル名「my-backup.sh」で作成しておきます。

# 指定されたディレクトリを圧縮して、曜日に基づいた名前のバックアップファイルを作成する

# 「#」で始まる行はコメント行です。実行時は無視されます。

backup_files=“/home /var/spool/mail /etc /root /boot /opt”

destination=“/mnt/backup”

day=$(date +%A)

archive_file=“backup-$day.tgz”

tar czf $destination/$archive_file $backup_files

手動で実行する場合は、シェルに対して以下を入力すればスクリプトを実行できます。

sh my-backup.sh

一度シェルスクリプトとしてファイルに保存しておけば、手動実行以外にも定刻に実行したり他のプログラムから呼び出したり、再利用が可能です。

また、他のプログラミング言語に見られるような変数や制御構造など、処理の自動化に役立つ機能もシェルスクリプトは備えています。

対話型と非対話型の違い

対話型シェル(インタラクティブシェル)は、ユーザーがコマンドを入力するたびにプロンプト($#などの記号)を表示し、即座に結果を返します。

一方、非対話型(バッチ処理)は、あらかじめ作成したスクリプトファイルを使用し、処理を自動実行します。

対話型は試行錯誤しながらの作業や学習に適しており、非対話型は定期的な自動処理や大量のデータ処理に向いています。

シェルの特徴とメリット

シェルはLinux系OSの管理をテキスト入力でおこなえるほか、シェルスクリプトを用意して業務を自動化できます。詳しく見ていきましょう。

コンパイル不要ですぐ実行できる

シェルのコマンドをテキスト形式のファイルに保存しておけば、シェルスクリプトとして実行できます。

C言語やJavaのようにコンパイル(テキスト形式で書かれたプログラムを機械語に翻訳する手順)は不要なので、テキストエディタがあれば簡単にスクリプト内容の変更や加筆ができ、OSを問わずスクリプトをやりとりできるため再利用性が高いのが特徴です。

基本操作(ファイル/ディレクトリの操作)が可能

サーバーOSの管理ではさまざまな操作が必要となりますが、よくおこなわれるのは、各種の記録を参照したり作成したりする操作です。

具体的には、WEBサーバーのログファイルを参照したり、バックアップの実施記録をつけたりしますが、いずれも基本的にはテキスト形式のファイルを操作すれば達成できます。

基本的な働きのコマンドをシェルの働きで組み合わせることで、利用者の必要とする複雑な条件での加工や抽出ができるのがシェルによる操作の特徴となっています。

作業の自動化と定型処理の省力化

シェルスクリプトを作成しておけば、同じコマンドを繰り返し実行できます。

例えば定期的にデータベース(MySQLまたはMariaDBで作成したもの)をバックアップする必要があるとします。

繰り返しのバックアップを自動化するシェルスクリプトを作成できます。例えば以下のようになります。

#!/bin/bash

 

# 現在の日付と時刻を取得

now=$(date +‘%Y%m%d_%H%M’)

# バックアップファイル名を設定

filename=“db_backup_$now.gz”

# バックアップフォルダのパスを設定

backupfolder=“/var/backup/db”

# バックアップファイルのフルパスを設定

fullpath_backup=$backupfolder/$filename

# ログファイルのパスを設定

logfile=$backupfolder/backup_log_$(date +‘%Y_%m’).txt”

 

# バックアップ開始のメッセージをログに記録

echo “データベースバックアップを開始しました: $(date +‘%Y-%m-%d %H:%M:%S’) >> $logfile

 

# MySQLデータベースのバックアップを取得し、gzipで圧縮

mysqldump –user=mydbuser –password=mypass –default-character-set=utf8 mydatabase | gzip > $fullpath_backup

 

# バックアップ終了のメッセージをログに記録

echo “データベースバックアップが完了しました: $(date +‘%Y-%m-%d %H:%M:%S’) >> $logfile

シェルスクリプトを定期的に実行するには、多くのLinux系OSに含まれるcrondソフトウェアが役立ちます。crondは指定のタイミングでシェルスクリプトや指定のプログラムを実行できます。

上記スクリプトを保存し、crondの設定ファイルを作成すれば、例えば毎晩3:50からバックアップを開始するよう設定できます。

開発・運用の効率が大幅に向上

複雑な手順の操作はシェルスクリプトにしておけば間違えずに実行できます。サーバー管理では、一台一台異なるサーバーのセッティングに対して、状況に応じたさまざまな操作を求められるため、カスタマイズしやすいシェルスクリプトは役立ちます。

perl・Ruby・Pythonのようなスクリプト言語を組み合わせて、より高度で大規模な業務手順をスクリプトとして作成・展開もできます。

また、gitやdockerなどのツールを導入しておくことで、開発やテストの工程でおこなわれる複雑な手順もカバーできるため、作業時間を短縮できます。

Shellを活用した業務の自動化や作業の効率化の技術を身に着けることで、インフラエンジニアとしての転職を考える際に希望の企業の面接で評価が高くなる可能性も十分にあります。

シェルの種類

シェルは、OSとユーザーのインタフェースとなる基本的なソフトウェアですが、Linuxの操作では頻繁に利用します。

シェルにはいくつもの種類があり、機能性なども異なります。WEBブラウザでFirefox・Chromeを選べるように、シェルも利用者の目的に応じて変更可能です。

主要なシェルをご紹介します。

Bash(Bourne Again Shell)

bashはボーンアゲインシェルとも呼ばれます。

bashは1980年代にブライアン・フォックス氏とGNUプロジェクトによりボーンシェル(sh)のフリーな代替として開発されました。

ボーンシェル(sh)に対する後方互換性を持ちながら、多くの付加機能があり使いやすかったため、多くのLinuxで標準のシェルとして採用されました。現在ではmacOSのターミナルでも使用できます。

sh(Bourne Shell)

shはボーンシェル、Bシェルとも呼ばれます。

1977年にアメリカの通信会社AT&Tでスティーブン・ボーン氏により開発されたUNIX系OSのためのシェルです。

他のシェルの元祖であり、現在でもいくつかのOSでは標準のシェルとして使用されています。

Zsh(Z Shell)

Zシェルとも呼ばれ、ボーンシェル(sh)を改良したシェルです。

他の多くのシェルを参考にして機能を取り入れ、オリジナルの機能も備えています。

プラグインとテーマをサポートしているためカスタマイズ性が高く、頻繁にシェルを利用する方に向いています。

csh(C Shell)

Cシェルは、1970年代にカリフォルニア大学のビル・ジョイ氏により開発されたUNIX系OSのためのシェルです。

Cシェル系とボーンシェル系(sh、bashなど)は異なる系統のシェルの一族で、Cシェルは名前のとおりC言語に似た文法の制御構造を備えるのが特徴です。C言語のプログラマーにとっては自然にシェルスクリプトを記述できるでしょう。

ksh(Korn Shell)

kshまたはコーンシェルは、1980年代後半にベル研究所のデビッド・コーン氏により開発されたUNIX系OSのためのシェルです。ボーンシェル(sh)との後方互換性とPOSIX規格への準拠をうたっています(POSIXは異なるOS間でソフトウェアの互換性・移植性を提供するための規格)。

kshは多くの機能があり、コマンドラインの編集、ジョブの制御、C言語に似た制御構造を持ち、ボーンシェル(sh)より動作が高速です。

bashやzshほど利用は多くありませんが、多くのUNIX系OSで利用できます。

なぜシェルは重要なのか

Windowsなどに見られるGUI(グラフィカルユーザーインターフェース)はマウスとアイコンで操作でき、分かりやすくとっつきやすいですが、サーバーを実務で使う専門家にとってはシェルを使う文字ベースの操作に多くの利点があります。文字ベースのため、設定内容を文書化しやすく、同僚に伝えるのも容易です。

シェルは、OSと利用者の仲介をするソフトウェアで、利用者が端末(ターミナル、などとも呼ばれます)に入力した文字を解釈してOSの理解できる情報に変換し、OSに動作を要請します。OSが作動し、何らかのレスポンスがあれば、利用者が読めるようなテキストの形で端末に表示をします。

Linuxサーバーの管理操作は、シェルを通じてコマンドを入力、結果として表示される文字を見てまた次の操作を繰り返すのが基本です。

シェルとOSの橋渡し機能

シェルは、ユーザーとLinux OS(オペレーティングシステム)の間を取り持つ重要な役割を果たします。

通常、OSの機能を直接操作するには、システムコールと呼ばれる複雑な命令を使う必要があります。しかし、シェルがあることで、lscpなど分かりやすいコマンドを使って、ファイル操作やプロセス管理を簡単におこなえます。

シェルは環境変数の管理、標準入出力の制御、パイプやリダイレクト機能も提供するため、複数のプログラムを連携させたり、処理結果を別のファイルに保存するなど柔軟な処理が可能です。

# パイプを使った処理の連携例

ps aux | grep apache | wc -l

実務でのシェルの使用例

シェルは幅広い業務で活用されています。

サーバー管理業務の例では、CPU使用率やメモリ使用量を定期的に監視し、異常値を検出した際にアラートを送信できます。

データ処理の分野では、大量のログファイルを解析して情報を抽出したり、データベースのバックアップを定期的にする作業を自動化できます。

# ログ分析の例

grep “ERROR” /var/log/application.log | tail -10

ソフトウェア開発の効率を高めるCI/CDパイプライン(継続的ビルド・デプロイシステム)でも、テストやデプロイ作業をシェルスクリプトで自動化するのが一般的です。

インフラ運用では、定期メンテナンスやシステム監視、障害対応など業務の多くをシェルによって効率化できます。

シェルの基本的なコマンド

シェルを効率的に使いこなすために、基本的なコマンドをご紹介します。

よく使う基本コマンド

サーバーOSの管理ではさまざまな操作が必要となりますが、よくおこなわれるのは、各種の記録を参照したり作成したりする操作です。

具体的には、WEBサーバーのログファイルを参照したり、バックアップの実施記録をつけたりしますが、いずれも基本的にはテキスト形式のファイルを操作すれば達成できます。

基本的な働きのコマンドをシェルの働きで組み合わせることで、利用者の必要とする複雑な条件での加工や抽出ができるのがシェルによる操作の特徴となっています。

例えば、テキストファイルを表示したり連結するには、次のコマンドが使用できます。

  • cat……ファイルの中身を表示します。
  • head……テキストファイルの冒頭の数行を表示します。
  • tail……テキストファイルの末尾の数行を表示します。

必要な箇所を抽出するには、次のコマンドを使用できます。

  • grep……ファイル内で特定のパターンに合う部分を抽出します。
  • cut……ファイル内の指定した列やフィールドを抽出します。
  • sort……ファイル内の行を昇順または降順で並び替えます。
  • uniq……ファイル内の連続する重複行を除去します。
  • split……ファイルを指定したサイズで分割します。

他の加工や変換は、次のコマンドがよく使用されます。

  • sed……ファイル内のテキストを変換します。文字列置換や行の削除など。
  • awk……ファイル内の指定フィールドを抽出したり、集計したりします。
  • tr……ファイル内の文字を置き換えます。

各コマンドの使用例は以下のとおりです。

コマンド

説明

$ cat error.log

error.logファイルの内容を(すべて)表示します。

$ head access.log

access.logファイルの冒頭10行を表示します。

$ tail -n 50 error.log

error.logファイルの末尾50行を表示します。

$ grep -e ‘https?://’ error.log

URLのような文字列を含む行を表示します。

$ cut -f 2-3 data.tsv

タブ区切りテキストファイルdata.tsvの2、3列目を表示します。

$ sort -n -r id.txt

各行に数値が記載されたid.txtファイルの行を大きい順に並び替えて表示します。

$ uniq id.txt

id.txtファイルに連続した同じ内容の行があれば1行のみ、他はそのまま表示します。

$ split -l 10000 access.log

access.logを1万行毎に分割したファイルを作ります。

$ sed ‘100,200s/foo/bar/’ in.txt

in.txtの100から200行目にある文字列fooをbarに置き換えて表示します。

$ awk ‘$5 >= 10000’ dir-list.txt

dir-list.txtのスペースで区切られた5番目の列が1万以上の行を表示します。

$ tr ‘a-z’ ‘A-Z’ < english.txt

english.txtの小文字のアルファベットを大文字に置き換えて表示します。

変数の使い方

シェルでは変数を使用して値を保存し、再利用できます。 変数には現在のシェルでのみ有効なローカル変数と、子プロセスにも引き継がれる環境変数があります。 環境変数を設定する場合はexportコマンドを使用します。

# ローカル変数の定義

name=“yamada”

 

# 環境変数の定義(sh系のシェル)

export PATH=“/usr/local/bin:$PATH

 

# 変数の参照

echo “Hello, $name

csh・tcshでは下記のようにします。

# 環境変数の定義(csh系)

setenv MY_VAR “Hello, World!”

echo $MY_VAR

コマンドの実行結果を変数に格納する場合は、コマンド置換$()を使用します。

# コマンド置換で現在の日時を取得

current_date=$(date)

echo “実施日: $current_date

条件分岐の基本構文

if文を使用して条件に応じて異なる処理を実行できます。 複数の条件を判定する場合はelifを使用し、どの条件にも該当しない場合はelseで処理を記述します。

if [ $score -ge 80 ]; then

    echo “優秀です”

elif [ $score -ge 60 ]; then

    echo “合格です”

else

    echo “不合格です”

fi

条件式では下記の判定ができます。

# ディレクトリの存在確認

dir_path=“/path/to/directory”

 

if [ -d $dir_path ]; then

    echo $dir_path は存在するディレクトリです”

else

    echo $dir_path は存在しないディレクトリです”

fi

複数の選択肢から条件を判定する場合はcase文が便利です。

case $day in

    “月曜日”|“火曜日”|“水曜日”|“木曜日”|“金曜日”)

        echo “平日です”

        ;;

    “土曜日”|“日曜日”)

        echo “休日です”

        ;;

    *)

        echo “不明な曜日です”

        ;;

esac

まとめ

Linuxのシェルは、OSとユーザーの橋渡しをする重要なプログラムです。基本コマンドの習得からシェルスクリプトの作成まで、業務の自動化や効率化を実現できます。

まずは基本的なコマンドから始めて、実際のLinux環境でシェル操作を体験してみましょう。