Ubuntu や一般的なLinuxディストリビューションで作業を学ぶ上で、シェル環境での作業に熟練することが重要な部分を占めます。 Linux に含まれる GNOME のようなグラフィカルなデスクトップ環境は、オペレーティング・システムにユーザー・フレンドリーなインターフェースを提供しますが、実際には、シェル環境は、グラフィカルなデスクトップ・ツールを使用して達成できるよりもはるかに大きな機能、柔軟性、および自動化を提供します。 シェル環境は、デスクトップ環境が利用できないときにオペレーティングシステムと対話するための手段も提供します。Ubuntuなどのサーバーベースのオペレーティングシステムや、完全に起動しない損傷したシステムで作業するときによくあることです。
したがって、この章の目標は、Ubuntu のデフォルトのシェル環境 (特に Bash シェル) の概要を提供することです。
1.1 シェルとは何か
シェルは、コマンドがプロンプトで入力されるか、スクリプトの形でファイルに入力されて実行できる対話型のコマンドインタープリタ環境です。 シェルの起源は、UNIX オペレーティングシステムの初期にさかのぼることができます。 実際、グラフィカルデスクトップが導入される前の Linux の初期には、シェルはユーザーがオペレーティングシステムと対話するための唯一の方法でした
長年にわたり、さまざまなシェル環境が開発されてきました。 最初の広く使われたシェルは、ベル研究所のスティーブン・ボーンによって書かれたボーンシェルでした。
さらにもう一つの初期の創造物は C シェルで、C プログラミング言語といくつかの構文の類似性を共有し、コマンドライン編集やヒストリなどのユーザビリティ強化を導入しました。
Korn シェル (Bell Labs の David Korn によって開発) は、Bourne シェルと C シェルの両方によって提供される機能をベースにしています。 このシェルは Bourne shell のオープンソース版として始まり、Brian Fox によって GNU プロジェクトのために開発され、Bourne shell と C shell の両方から提供される機能をベースにしています
1.2 Gaining Access to the Shell
GNOMEデスクトップ環境から、トップバーのActivityオプションを選択し、検索バーにターミナルと入力してターミナルアイコンをクリックすると、ターミナルウィンドウからシェルプロンプトにアクセスすることができます
Ubuntuサーバーにリモートでログインする際、例えばSSHを使って、ユーザーにもシェルプロンプトが提示されます。 SSHを使用してリモートサーバーにアクセスする際の詳細については、「UbuntuでのSSHキーベースの認証の設定」という章で説明します。
1.3 プロンプトでコマンドを入力する
コマンドは、コマンドを入力してEnterキーを押すだけで、シェルのコマンドプロンプトに入力されます。 いくつかのコマンドは静かにタスクを実行するが、ほとんどのコマンドはプロンプトに戻る前に何らかの形で出力を表示する。 たとえば、ls コマンドは、現在の作業ディレクトリにあるファイルとディレクトリを表示するために使用できます:
$ ls
Desktop Documents Downloads Music Pictures Public Templates Videos
利用できるコマンドはシェル自体に組み込まれているか、物理ファイルシステム上に存在するものです。 コマンドのファイルシステム上の位置は、which コマンドを使用して特定することができます。 たとえば、ファイルシステム上のどこに ls 実行ファイルが存在するかを調べるには、
$ which ls alias ls='ls --color=auto' /usr/bin/ls
ls コマンドが /usr/bin ディレクトリに存在することは明らかである。 また、エイリアスが設定されていることにも注意してください。このトピックは、この章の後の方で取り上げます。 シェルに組み込まれているコマンドのパスを見つけるために which コマンドを使用すると、実行ファイルが見つからないことを示すメッセージが表示されます。 例えば、history コマンド (ファイルシステム上に実行ファイルとして存在するのではなく、実際にシェルに組み込まれている) の場所を見つけようとすると、次のような出力が得られます:
$ which history/usr/bin/which: no history in (/home/demo/.local/bin:/home/demo/bin:/usr/share/Modules/bin:/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin)
1.4 コマンドに関する情報を得る
Linux シェルで利用できる多くのコマンドは、始めから不可解に見えるかもしれません。 あるコマンドが何をするのか、どのように使うのかについての詳細な情報を得るには、コマンド名を引数に指定したmanコマンドを使用します。 例えば、pwdコマンドについて詳しく知るには、
$ man pwd
上のコマンドを実行すると、pwdコマンドの詳しい説明が表示されます。 多くのコマンドは、-helpコマンドラインオプションを付けて実行すると、さらに情報を提供します。
$ wc --help
1.5 Bashコマンドライン編集
初期のシェル環境では、いかなる形式の行編集機能も提供されていませんでした。 これは、入力中の長いコマンドラインの先頭でエラーを発見した場合、後続の文字をすべて削除し、エラーを修正してからコマンドの残りを再入力しなければならないことを意味します。 幸いなことに、Bashには次の表に示すような幅広いコマンドライン編集オプションが用意されています。
キーシーケンス | アクション | ||
Ctrl-b または左矢印 | Move cursor back one position | ||
Ctrl-> Move cursor back one position | Ctrl-b または左矢印Move cursor back one position | ||
Ctrl-b または左矢印 | カーソルを1つ前に移動 | ||
削除 | 現在表示している文字を削除します。 カーソルの下にある文字 | ||
バックスペース | カーソルの左にある文字を削除 | ||
Ctrl-? | 前の変更を取り消す (前の変更をすべて取り消すにはこれを繰り返す) | ||
Ctrl-> (コントロールキー)a | カーソルを行頭に移動 | ||
Ctrl-e | カーソルを行末に移動 | ||
Meta- | カーソルを1ワード進める | ||
Meta-b または Esc キーを押しながら b | カーソルを1ワード戻す | ||
Ctrl-> | カーソルを1ワード前に動かす。l | 現在のコマンド以外の画面を消去 | |
Ctrl-k | 現在のカーソル位置から行末まで削除 | ||
Meta-> | 現在の単語の終わりまで削除 | ||
Meta-DEL または Esc キーを押しながら DEL | 現在の単語の始まりまで削除 | ||
Ctrl-> DEL | 現在の単語の終わりまで削除w | 現在のカーソル位置から前の空白文字まで削除 |
Table 9-1
1.6 シェルでの作業履歴
コマンドライン編集機能に加えて、Bashシェルはコマンドラインの履歴もサポートしています。 History コマンドを使用すると、以前に実行したコマンドのリストを見ることができます:
$ history1ps2ls3ls –l /4ls5man pwd6man apropos
さらに、Ctrl-p (または上矢印) と Ctrl-n (または下矢印) で、以前に入力したコマンドを前後にスクロールできます。
もう一つの方法は、’!’文字の後に繰り返したいコマンドの最初の数文字を入力し、Enterキーを押すことです。
$ cat list.txt
同様に、すべてのファイル名を引数として指定することにより、複数のテキストファイルの内容を表示することができます:
$ cat list.txt list2.txt list3.txt list4.txt
それぞれの名前を入力する代わりに、パターンマッチを使ってある基準に一致する名前のすべてのファイルを指定することが可能です。 たとえば、’*’ ワイルドカード文字を使用して、上記の例を簡略化できます:
$ cat *.txt
上記のコマンドは、拡張子が .txt で終わるすべてのファイルの内容を表示します。
$ cat list*.txt
1 文字のマッチは ‘?’ 文字で指定できます。
$ cat list?.txt
1.8 ファイル名とパスの補完
ファイル名やパス全体を入力する代わりに、またはパターンマッチを使って入力の量を減らす代わりに、シェルではファイル名の補完機能を提供しています。 ファイル名補完機能を使用するには、ファイル名またはパス名の最初の数文字を入力し、Esc キーを 2 回押すだけです。 シェルは、入力された文字と一致するディレクトリ内の最初のファイルまたはパス名でファイル名を補完してくれます。
1.9 Input and Output Redirection
前述のように、多くのシェルコマンドは実行されると情報を出力します。 デフォルトでは、この出力は stdout という名前のデバイスファイルに送られ、これは本質的にシェルが実行されている端末ウィンドウまたはコンソールになります。
コマンドからの出力は、’>’ 文字を使用して stdout からファイルシステム上の物理ファイルにリダイレクトすることができます。 例えば、ls コマンドの出力を files.txt という名前のファイルにリダイレクトするには、以下のコマンドが必要です:
$ ls *.txt > files.txt
完了すると files.txt には現在のディレクトリにあるファイルのリストが表示されます。 同様に、stdin の代わりにファイルの内容をコマンドに入力することもできる。 例えば、ファイルの内容をコマンドの入力としてリダイレクトするには、次のようにする:
$ wc –l < files.txt
上記のコマンドは files.txt ファイルに含まれる行数を表示する。
注意すべき点は、「>」リダイレクト演算子は使用時に新規ファイルを作成するか既存のファイルを切り詰めることである。 既存のファイルに追加するには、’>>’ 演算子を使用する。
$ ls *.dat >> files.txt
標準出力に加えて、シェルは標準エラー出力として stderr も提供する。 コマンドからの出力は stdout に向けられるが、コマンドによって生成されたエラーメッセージは stderr に向けられる。 つまり、stdout がファイルに向けられている場合でも、エラーメッセージはターミナルに表示されます。
$ ls dkjfnvkjdnf 2> errormsg
コマンドが完了すると、dkjfnvkjdnf というファイルが見つからなかったというエラーが errormsg ファイルに記録される。
stderr と stdout の両方を &> 演算子を使用して同じファイルにリダイレクトすることができます:
$ ls /etc dkjfnvkjdnf &> alloutput
実行を完了すると、alloutput ファイルに /etc ディレクトリのコンテンツのリストと、 存在しないファイルをリストしようとしたときのエラー メッセージの両方が含まれます。
1.10 Bash シェルでパイプを使う
I/O リダイレクトに加えて、シェルではあるコマンドからの出力を別のコマンドへの入力として直接パイプで送ることができます。 パイプ操作は、コマンドライン上の2つ以上のコマンドの間に「|」文字を置くことで実現されます。 例えば、システム上で動作しているプロセスの数を数えるには、ps コマンドの出力をパイプで wc コマンドに渡します:
$ ps –ef | wc –l
コマンドラインで実行可能なパイプ操作の数に制限はありません。 たとえば、Smith という名前を含むファイルの行数を調べるには、次のようにします:
$ cat namesfile | grep Smith | wc –l
1.11 エイリアスの設定
シェル環境に習熟すると、同じ引数を持つコマンドを頻繁に発行することになると思われます。 例えば、ls コマンドに l と t オプションを付けて使用することがよくあります。
$ ls –lt
コマンドを発行する際の入力量を減らすために、コマンドと引数に対応するエイリアスを作成することが可能です。 例えば、文字 l を入力すると ls -lt コマンドが実行されるようなエイリアスを作成するには、次の文を使用します:
$ alias l="ls –lt"
コマンドプロンプトで l を入力すると元の文が実行されるようになりました。 シェル自身は、シェルの動作を変更するためにユーザが変更することができる多くの環境変数を設定します。 現在定義されている変数のリストは env コマンドで得ることができる。 これは、シェルがコマンドプロンプトで入力されたコマンドを検索するディレクトリと、その順序を定義するものである。 新しくインストールされた Ubuntu システムのユーザー アカウントの PATH 環境変数は、おそらく次のように設定されます:
$ echo $PATH/home/demo/.local/bin:/home/demo/bin:/usr/share/Modules/bin:/usr/local/bin:/usr/ bin:/usr/local/sbin:/usr/sbin
もうひとつの有用な変数は、現在のユーザーのホーム ディレクトリを特定する HOME です。 たとえば、シェルがホームディレクトリにある scripts ディレクトリのコマンドも探すようにしたい場合、PATH 変数を次のように変更します:
$ export PATH=$PATH:$HOME/scripts
既存の環境変数の現在の値は echo コマンドを使って表示できます:
$ echo $PATH
自分自身の環境変数は export コマンドを使って作ることができます。 たとえば、次のようになります:
$ export DATAPATH=/data/files
コマンドからの出力を環境変数に割り当てる便利なトリックは、コマンドをバッククォート (`) で囲むことです。 たとえば、現在の日付と時刻を NOW:
$ export NOW=`date`$ echo $NOWTue Apr 2 13:48:40 EDT 2020
という環境変数に割り当てる場合、シェル環境に入るたびに設定する必要がある環境変数やエイリアスの設定があれば、ホームディレクトリの .bashrc というファイルに追加しておくとよいでしょう。 たとえば、次の .bashrc ファイルは、DATAPATH 環境変数とエイリアスの設定を行います:
1.13 シェルスクリプトの作成
これまでは、Bash シェルの対話型の性質だけに焦点を当ててきました。 対話的というのは、プロンプトでコマンドを一つずつ手動で入力し、それを実行することを意味します。 実際、これはシェルができることのほんの一部に過ぎない。 シェルの最も強力な機能の1つは、シェルスクリプトを作成する機能です。 シェルスクリプトとは、基本的に、シェル環境内で実行可能な一連のステートメントを含むテキストファイルであり、タスクを実行することができます。 コマンドを実行する機能に加えて、シェルは for や do ループ、if 文など、スクリプト言語に期待されるプログラミング構成の多くを提供します。
残念ながら、シェルスクリプトの詳しい概要は本章の範囲外です。 しかし、シェルスクリプトに特化した多くの書籍やWebリソースがあり、ここで紹介するよりもはるかに適切な内容となっている。 したがって、このセクションでは、シェルスクリプトのごく一部を紹介します。
シェルスクリプトを作成する最初のステップは、ファイル (この例では、simple.Scala という名前にします) を作成することです。sh) を作成し、最初の行として以下を追加します:
#!/bin/sh
#! は “shebang” と呼ばれ、スクリプトの実行に必要なインタープリターのパスがその行の次のアイテム (この場合、/bin にある sh 実行ファイル) であることを示す特別な文字のシーケンスです。
次のステップは、簡単なスクリプトを書くことである:
#!/bin/shfor i in *do echo $idone
このスクリプトが行うことは、現在のディレクトリのすべてのファイルを繰り返し、それぞれのファイル名を表示することである。
$ sh simple.sh
ファイルを実行可能にするために (それによって sh コマンドに渡す必要がなくなる) chmod コマンドを使用することができます。 例:
$ ./simple.sh
1.14 まとめ
Ubuntu Essentials のこの章では、Bash シェル環境について簡単に見てきました。 グラフィカルなデスクトップ環境の世界では、オペレーティング システムの真のパワーと柔軟性は、ユーザーフレンドリーなデスクトップ インターフェイスの下に降りて、シェル環境を使用することによってのみ利用できることを忘れがちです。 さらに、デスクトップがインストールされていないサーバーベースのシステムを管理・保守する必要がある場合や、デスクトップまたは Cockpit インターフェイスが起動しないほど損傷したシステムを修復する場合にも、シェルに精通していることは必要不可欠です
。