MAGAZINE

キャリテク!マガジン

コラム

Linuxのシェルとは何か、シェルスクリプトとの関係は?

こんにちは、吉政創成 アシスタントの菱沼です。

今回も「さわって学ぶLinux入門テキスト/赤星リナ氏著(マイナビ出版)」を片手に勉強していきます。どうぞ超初心者の方、お付き合いいただければ幸いです。
なお、テキストではCentOSが使用されています。CentOS8は2021年12月末にサポートが終了し、次世代へ移行するという話があるため、詳細はそこまで掘り下げず、コマンドの確認が中心となります。

では今回はテキストの5章に当たる部分、シェルについて学んでいきます。

■シェルとは何か、シェルスクリプトとの関係は?

さて、シェルとは何かという点からですが、前回、シェルスクリプトといものを書いて実行していたりします。
例えば、サーバのログデータを取得してZipにして落としたり、バックアップサーバに送信するのを自動化したりといった処理は通常、複数行にわたってコマンドや変数使って実行したい内容を書いていかなくてはいけませんが、それをテキストファイルに書いて保存しておけば、たった1行で実行することができます。そういったファイルをシェルスクリプトと呼びます。
さて、では今回学ぶ「シェル」とは何なのか。テキストをちょっと戻って確認してみます。

P.19
OSはさまざまな仕事をしていますが、こうした基本的な機能を処理するプログラムのことを「カーネル(Kernel:核とか中心といった意味)」といいます。カーネルこそがLinuxの実態で、心臓ともいえるプログラムですが、ユーザーからのコマンドを理解する能力は持っていません。命令する側(人)とカーネルの間には「シェル(shell)」という通訳プログラムが必要です。シェルは、受け取ったコマンドをカーネルにわかるように翻訳して伝えます。カーネルで処理が終わったら、こちらにわかるように翻訳して結果を表示してくれます。
シェルにはさまざまな種類があり、使用するシェルを変えることもできます。Linuxで一般的によく使われているシェルは「bash(バッシュ)」です。

人間語を機械語に変えてお話ししてくれる通訳さんとか、電話や来客を取り次いでくれる受付の人といったイメージでしょうか。図に置き換えると多分こんな感じだと思います。

ちなみに「シェル」と「シェルスクリプト」の違いですが、シェルは人間が理解できる形で書かれたコマンドを機械語に翻訳してカーネルに渡しますが、シェルスクリプトはシェルが理解できるコマンドをまとめて一つのファイルにしたものだそうです。また、シェルは来たものを順番に一つずつ処理します(インタプリタ)が、シェルスクリプトは一つのファイルにまとまっているので、一気に処理をお願いできるということのよう…。
イメージとしてはこんな感じかなと思います。

ところで、文中にでてきた「bash」という言葉ですが、これは「shell」のひとつで、他にもお仲間がおり、「sh」「ksh」「csh」「tcsh」「zsh」があるそうです。
それぞれ使われている言語が違うなどの特徴があるようですが、「bash」は「shell」の中で最もベーシックで使いやすいコマンドということで、「bash」が使われることが多いということでした。どれを使用すればいいのかは最終的に好みだそうです。

ちなみに、「bash」は「sh」の後継で、構文などの基本的な使用は同じな上位互換という存在だそうです。 興味がある方は検索してみてくださいね。

■シェルに関係するもの

便利な入力補助機能

Tab:コマンドやファイル名を途中まで入力してから押すと、コマンドが補完されるか、候補が並ぶ

矢印(↑↓):前に入力したコマンドを表示したり、ファイル名やコマンドを変更したりして再利用できる。
Ctrl+c:今実行している処理をキャンセルできる
Ctrl+d:ログアウトする(コマンド「exit」と同じ動作)
Ctrl+l:画面の表示をクリアできる(コマンド「clear」と同じ動作)
Ctrl+r:今まで入力したコマンドを検索して、実行できる
Ctrl+u:カーソルのある位置から左側を切り取り(削除)
Ctrl+k:カーソルのある位置から右側を切り取り(削除) Ctrl+y:直前に切り取った文字を張り付け

履歴の操作

bashにはコマンドの入力履歴が保存されているのだそうです。その履歴を使用して実行することもできます。

①過去に入力したコマンドの一覧を表示させる[history]
入力すると、日付や時刻と共に、過去に入力した履歴がずらーっと表示されます。実行結果は次の画像。

②履歴から削除する
間違えたコマンドも履歴で出てくるのでちょっと恥ずかしく思い、証拠隠滅を図りました。

③履歴からコマンドを実行する
履歴から実行したいコマンドがあった場合は[!(番号)]と入力すると実行できます。

入力を簡単にするエイリアス

エイリアス[alias]を使えば、長いコマンドを短くしたり、結果の文字に色付けしたりができるようです。
説明を読むとユーザー辞書とか、条件付き書式みたいなイメージかな? と思うのですが、確認していきます。

①[alias]の中身を確認してみた
まず、[alias]と入力すると、現時点で[alias]に登録されている内容が表示されます。

[grep]や[ls]の項目を見ると「color」と書かれていて、どうやら色付けが設定されているらしいことがわかります。実際、[grep]と[ls]を実行すると青文字とか赤文字とかになっていましたよね。こうやって設定されていたんですね。
[alias]で設定されているものは、コマンドの前に「バックスラッシュ」をつければ一時的に無効にできるそうなので、まずは普通に実行した後で無効化したらどうなるかというのを試してみました。

実行してみると、色があるとなしとでは見やすさが大違いですね。
見づらいなーと思う部分にはこうやって色文字にしてみるのもいいのかもしれません。

②エイリアスを設定する[alias (名前)=’(コマンド名)’]
例えば、[ls -al]を[alias]に登録してみます。「=」の前後には空白を入れてはいけないそうです。
まずは普通に[ls -al]を実行してみた後、[alias]に登録して、実行してみます。

無事登録されましたし、結果も普通に入力した時と同じ結果でした。

③エイリアスから削除したい[unalias (名前)]
※一時的に使用をやめたい場合は、「バックスラッシュ」をコマンドの前につけます。

複数のコマンドを続けて実行したいときは[|(パイプ)]

例えば、履歴の中から特定のコマンドを抜き出したいといったときや、テキストファイルの中から同じデータがあった場合は一つにまとめてほしいといったような、何かの処理をしたいときには[|(パイプ)]をつけてあげれば同時に複数個の処理が進められるそうです。

何個付けられるんだろう…って気になるじゃないですか。
聞いてみましたところ、最大何個かは確かめたことはないけれど、大体使っても2,3個程度だそうです。その理由は、たくさんつなげてしまえばその分だけ処理に時間が掛かりますし、サーバにかかる負荷も上がりますので、場合によっては全然返答がないということになるからだそうです。なので、負荷が上がりそうな処理を複数個するのであればシェルスクリプトにしてしまうそうですが、こちらもまた書き方によっては同様の現象を引き起こすので、負荷が掛からないようにスクリプトを書く必要があるそうです。ほー。

出力先の変更(リダイレクト)

例えば、キーボードを使ってコマンドを入力すると、ディスプレイに出力されます。こうした流れを標準入力と標準出力と言うのだそうです。この入力先と出力先は切り替えられるようで、その切り替えを行う処理のことを「リダイレクト」というのだそうです。「リダイレクト」に使うのは下表の記号です。

引用:P.199

標準出力の出力先を変更する(データは上書き)
>> 標準出力の出力先を変更する(データは追記)
標準入力の入力元を変更する
2<標準エラー出力の出力先を変更する(データは上書き)
2>>標準エラー出力の出力先を変更する(データは追記)

<使用例>
コマンドの結果をファイルに上書きで書き込みたい:コマンド > ファイル名
コマンドの結果をファイルに追記したい:コマンド >> ファイル名
ファイルAを読んだ後にコマンドを実行、結果はファイルBに上書き:コマンド < ファイルA > ファイルB

シェル変数と環境変数

プログラミングには欠かせないという変数はシェルでも使われるそうです。
変数とは値を入れておく箱のようなもので、ここに入っている値をどこかの関数で使用したり、どこかの関数で得た値を保存したりといったことができます。
ただ、変数は変数でもLinuxには「シェル変数」と「環境変数」というものがあるそうです。

引用:P209
〇シェル変数と環境変数の役割と違い
・シェル変数:いま実行しているシェル内だけで有効
・環境変数:いま実行しているシェルと、そこから実行されるシェルやプログラムにも引き継がれる変数

(中略)
シェルにあらかじめ用意されている変数を「組み込み変数」といい、シェル変数や環境変数にも組み込み変数があります。シェル変数は、いま実行しているシェルの中だけで有効な変数ですが、環境変数はさまざまなプロセス(プログラム)から参照することができる変数です。
シェルに情報を伝えるために独自の変数を設定することもできます。変数を定義するには次のように指定します。

変数名=値
変数を定義するときには、以下のことに気を付けます。
・「=」の前後にスペースを入れない
・変数名の先頭に数字は使わない
・大文字と小文字を区別する
・値にスペースを入れたいときは「’(シングルクォーテーション)」または「”(ダブルクォーテーション)」で囲む
-----

では変数に関係するコマンドを一覧にしてみました。

echo $ 変数名変数の設定と確認 (画面に文字や数字、変数の内容を表示する。変数の内容を表示したい場合には変数名の前に「$」をつけ、正確に変数名を記述する)
setシェル変数と環境変数をすべて表示する
env、printenv環境変数だけ表示する
unset 変数名環境変数、シェル変数の削除
export シェル変数名=’値’シェル変数を環境変数にする (いま動いているシェルの中でのみ使用できるシェル変数を、子プロセスでも使えるようになります。)

引用:P211
環境変数にはいろいろなものがあります。

主な変数説明
PATHコマンドやプログラムの場所を示すディレクトリの一覧
PWDカレントディレクトリ
HOMEカレントディレクトリのホームディレクトリ
HOSTNAMEコンピュータ名
LANG今使っている言語環境
LOGNAMEシェルのユーザー名
PS1プロンプトに表示する内容
UIDユーザーID
USERユーザー名

引用:P.222
今まで見てきた変数や設定は、終了するとすべて消えてしまいます。設定を保存したい場合はbashに関する設定ファイルに書き込みます。
(中略)環境変数やシェル変数、エイリアスなどを変更する場合は、ユーザーごとのホームディレクトリに存在する「.bash_profile」や「.bashrc」に記述します。
―――

ということで、設定を変更したならしっかりと保存をしないまま終了してしまえば次回に引き継がれないそうです。
設定を保存する場所は環境設定ファイルである「.bash_profile」や「.bashrc」だそうですが、どういったものなのでしょうか。次で確認します。

環境設定ファイル

引用:P.222
環境設定でとくに大切なファイルは以下の通りです。
「/etc/pforile」
ログイン時にすべてのユーザーが読み込みます。
「.bash_profile」
ユーザーごとのホームディレクトリに存在する「.bash_profile」はログイン時に実行されます。ここには環境変数を設定します。
「.bashrc」
Bashが起動するたびに実行されます。「.bashrc」にはエイリアスなどを設定します。
----

ということだそうですが…。
そもそもシェルにはログインした時に起動するログインシェルと、それ以外の非ログインシェルがあるそうで、それぞれ起動時に読み込むものと、その順番が異なるようです。

<ログインシェルと非ログインシェルの読み込み>

順番ログインシェル非ログインシェル
/etc/profile ※全ユーザーに適用~/.bashrc
~/.bash_profile ※特定ユーザーに適用/etc/bashrc
~/.bash_login ※②がない場合は繰り上げ/etc/profile.d
~/.profile ※③がない場合は繰り上げ ※sh等、別のシェルからも読み込まれる 
~/.bashrc 
/etc/bashrc ※システム全体の関数、エイリアスの設定 

ログインシェルはログイン直後に「/etc/profile」を読み込むため設定が初期化されます。全ユーザーに設定を反映したいなら「/etc/profile」に、ユーザーごとでいいのなら、「.bash_profile」や「.bashrc」に記述したらいいようです。
またbashが起動されるたびに読み込ませたい設定がある場合には「~/.bashrc」に書いてあげるようです。

参考:
Linuxで環境変数を永続化させる方法と手順について|Rainbow Engine
ログインシェルとは?非ログインシェルとの違いも併せてご紹介|Rainbow Engine
環境変数の設定(~/.bash_profile, ~/.bashrc)|わくわくBank

編集は、対象のファイルの名前・内容を確認した後、バックアップを取った上で、[vi]コマンドで編集しましょう、とのことです。

<バックアップの取り方>
[cp (ファイル名) (バックアップファイル名)]でバックアップを取る→[ls]で確認

内部コマンドと外部コマンド

引用:P209
〇内部コマンドと外部コマンド
[type]コマンド:コマンドの種類を確認(内部コマンド、外部コマンドなど)
[which]コマンド:外部コマンドファイルのパスを表示する

引用:P.219
コマンドは「内部コマンド」と「外部コマンド」に分けられます。内部コマンドはシェルに組み込まれています。外部コマンドはコマンドごとにプログラムファイルとして保存されています。
内部コマンドはすぐに実行できますが、外部コマンドはプログラムを実行しているので、プログラムファイルの場所がわからないと実行できません。
----

内部コマンドは標準でLinuxに搭載されているもので「/bin」配下にありますが、外部コマンドはLinuxに標準搭載されているものではなく、ディストリビューションによって異なり、またユーザーが追加したもので、基本的には「/usr/bin」配下に保管されているようです。
この二つの違いがどう影響するのかよくわからなくて調べてみたところ、シェルスクリプトを書く時に、実行環境が異なる人が使うかもしれない場合には絶対パスで書くなどの注意をしておいた方がいいということのようです。
参考:【Linux】内部コマンドと外部コマンドの違い【シェル】|やっさんハック

内部コマンドと外部コマンドに関連するコマンドの一覧はこちらです。

echo $PATH外部コマンドのプログラムファイルの場所の確認
type コマンド名コマンドの種類を確認する
which コマンド名外部コマンドの絶対パスを表示する

ということで、今回はシェルとそれに関連するコマンドについて確認してきました。
お付き合いいただきありがとうございました。

過去の連載記事

  1. Linuxのユーザー管理とアクセス権の設定方法
  2. Linuxのテキストエディタviと、できたファイルの表示&検索
  3. Linuxでファイルを作ってコピーしてみた(touch/cp)
facebook シェアシェア
LINE シェアシェア