はじめに
- コマンドを入力する
- コマンドの実行結果を出力する
これらのインターフェースを提供するソフトウェアを 端末エミュレータ という。
【代表的な端末エミュレータ】
- コマンドプロンプト(Windows)
- ターミナル(macOS)
端末エミュレータは、その言葉の通り 物理的な端末を模倣(emulate)したソフトウェア である。
terminal は訳すと「端末」だが、物理的端末ではなく端末エミュレータを指して使われることが多い。terminal は「末端の、終着駅」などの意味も含む。
また「端末」は広義の意味では「ユーザがシステムと対話するためのインターフェース全般」を指す場合もある。
このように、歴史的に用途や姿形が大きく変化してきたために、文脈やその人の背景知識によって異なるものを指す用語がいくつかあるので、理解を深めたい。
かつての端末(TTY)
Terminal
原始的な入出力機器から構成される物理的装置。
- 入力装置
- タイプライタ
- 出力装置
- プリンタ
- 媒体は紙
出典:Dominic Alves from Brighton, England - ASR 33 Teletype, CC 表示 2.0
https://commons.wikimedia.org/w/index.php?curid=4259023による
現代で「入出力装置」と言えば、キーボードとディスプレイであるが、かつてはタイプライタとプリンタ(印字機)であり、この時代の端末は TTY(teletypewriter) と呼ばれた。
端末自身は CPU やメモリなどといった、コンピュータとして計算を実行するための能力を持たない。
この頃の端末は、接続された大型コンピュータへの文字入力や印字といったデータの送受信のみを行うシンクライアント的な存在だったと言える。
元来、端末と大型コンピュータは別々に存在していたが、コンピュータがどんどんと小型化していくと同時に端末装置が端末エミュレータとしてソフトウェア化され、さらに端末エミュレータ自体もコンピュータに搭載されたため、もはや両者は明確に区別することが難しくなった。
物理的端末装置はコマンドを解釈しない。
端末エミュレータもコマンドを解釈しない。
かつてのコンソール
コンピュータ初期のメインフレームと呼ばれる大型コンピュータは、キーボードとディスプレイで構成される 端末 に直に接続されていた。
この構成における「計算」はメインフレーム上で行われ、端末はメインフレームに入力を与える、メインフレームが出力した計算結果を表示する役割を担っていた。
このとき特に、端末上でオペレータ(管理者)が操作する黒の専用画面は コンソール と呼ばれた。
IBM - https://digitaltmuseum.no/011015240147/22-0-ibm-modell-360-370, CC 表示-継承 4.0
https://commons.wikimedia.org/w/index.php?curid=113477774による
コンソールは CUI 環境であるため、ターミナルアプリ のようなウィンドウ、タブ、マウス操作という GUI 的な機能は備えていない。
出典:Jason Scott - Flickr: IMG_9976, CC 表示 2.0
https://commons.wikimedia.org/w/index.php?curid=29457452による
またコンソールは カーネルに直結している という大きな特徴を持つ。
ケーブルを途中で抜き差しすることは想定されておらず、
- 1 台のコンピュータ(メインフレーム)
- 1 つの端末
- 端末上の 1 つの専属コンソール
- 1 人の専属オペレータ
といった 1 対 1 の対応関係で設計されていた。
現代のコンソール(仮想コンソール、TTY)
現代のコンソールは、かつてのコンソールを仮想化したものである。
仮想化の利点は、本来、端末上に 1 つしかないコンソールを同時に複数扱える点にある。
仮想化された現代のコンソール画面も、かつてのコンソール同様に黒い画面であることには変わりないが、内部ではカーネルが /dev/tty1
〜 /dev/tty6
の デバイスファイル として管理している。
かつてのコンソールはコンピュータ(ディスプレイ)とコンソールが一体化しているため、ディスプレイに映し出されるのは常に 1 つのコンソールであるが、仮想コンソールは同じディスプレイ上に映し出されるコンソールを Ctrl + Alt + F1
〜 F6
で切り替えることができる(macOS の場合 command + fn + F1
)。
どの仮想コンソールがディスプレイに映し出されているのかは $ tty
によって確認することができる。
$ tty
は現在のシェルプロセスの 標準入出力 が接続されたデバイスファイルを表示するコマンドである。
$ tty
/dev/tty1
$ tty
/dev/tty2
/dev/ttyX
は getty
によって標準入出力と接続される。
現代の端末 / 端末エミュレータ
Terminal Emulator
物理端末 をソフトウェアによって模倣(emulate)したアプリケーション。
- macOS の ターミナル
- Linux の GNOME Terminal
- Windows の コマンドプロンプト
(Windows の cmd.exe
は端末エミュレータに分類されるが、PowerShell は本来シェルでありながら独自の端末環境を提供する。一方、Windows Terminal はこれらをホストする端末エミュレータとして動作する。)
かつての物理端末と同様に、端末エミュレータ自体はコマンドを解釈、実行する機能を持たない。
端末エミュレータは、キーボードを介してユーザーからテキスト形式で入力されたコマンドを シェル に渡し、その後、実行結果をシェルから受け取りユーザに表示する。
端末エミュレータの標準入出力は、ユーザが起動したアプリケーションとしてのターミナルプロセスが仲介しており、実際には 疑似端末(PTY) を通じてシェルと通信している。
コマンドによる CUI 操作でも、実際にはウィンドウ、タブ、ペイン操作、マウス操作、コピー&ペーストなどができる GUI 環境上で動作している。Wikipedia ではこの状況を 「GUI 環境内で CLI(コマンドライン・インタフェース)を提供する」 と上手に表現されていた。
コンソールは完全な CUI 環境で動作する ため、混同しがちな「ターミナルアプリ」と「コンソール」の大きな違いの一つがこの点にある。
デスクトップ環境 のない環境では、端末エミュレータは存在しない。一方、デスクトップ環境のない環境でも仮想コンソールは存在する。
端末エミュレータは、複数のタブを開くことができ、タブごとにシェルを立ち上げることができる。
ウィンドウシステム を搭載しているデスクトップ環境では、アプリケーションとしての端末エミュレータを複数起動させることもできる。
また端末エミュレータに各種製品が存在し、動作する環境や特徴が異なる。
アプリケーション名 | 動作する環境 | 特徴 |
---|---|---|
ターミナル | macOS | macOS 標準搭載。 Bash や Zsh などのシェルへアクセスできる。 |
iTerm2 | macOS | サードパーティ製。 タブ分割、複数ペイン表示、ショートカットなどの機能、カスタマイズ性が豊富。 |
xterm | X Window System | Unix 系 OS(特に Linux)で利用される。 カスタマイズ性が低いが軽量で動作が軽く、基本機能に特化している。 リソースが少ない環境や古いシステムでの使用に適している。 |
GNOME Terminal | X Window System | GNOME デスクトップ環境に標準搭載。 高度なカスタマイズ機能を持つ。 |
Windows Terminal | Windows | Windows 11 から標準搭載。 Windows 10 ではインストールが必要。 |
コマンドプロンプト | Windows | Windows 標準搭載。 |
端末エミュレータは、ローカルマシンの OS 上でシェルを動作させるだけでなく、SSH などを利用してネットワーク経由でリモート環境のサーバのシェルに接続し、操作する用途にも使われる。
擬似端末 / PTY
pseudo terminal
従来の 物理的な端末 を擬似的に再現した端末のこと。または端末エミュレータ上で論理的に分割された接続セッションのこと。
擬似端末(PTY)という概念を導入することで、1台のPC上で複数の端末(セッション)を並行して操作・利用することが可能になる。
擬似端末はカーネルによって /dev/pts/0
や /dev/pts/1
のような デバイスファイル として作成される。
PTY は マスター と スレーブ のペアによって構成される。
- マスター(Master)
/dev/ptmx
- スレーブに対して指示を出したり、スレーブからの出力を受け取る
- 端末をエミュレートするプログラム側(
$ ssh
、$ screen
、$ tmux
、端末エミュレータなど) - UI を担当
- 主従関係を表す用語が差別的な表現であることから、現代では コントローラ と呼ばれることもある
- スレーブ(Slave)
/dev/pts/N
- 実際にシェルやコマンドが接続され、標準入出力をマスターに渡している裏方
- 端末としての振る舞いを担当
- シェルが標準入出力として利用する
ユーザからのコマンド入力は端末エミュレータからマスターに渡り、スレーブを経由してシェルへ送信される。
反対にコマンドの実行結果は、シェルからスレーブが受信し、マスターを経由して端末エミュレータに届けられる。
このように擬似端末は、仮想的に端末(TTY)をエミュレート(再現) しているにすぎない。
以下のコマンドで内部的に利用される。
ターミナル
macOSに標準搭載されている 端末エミュレータ。
文脈によっては、端末エミュレータそのものを指す場合がある。
シェル
コマンドを解釈して、カーネルに対する システムコール を実行するソフトウェア。
シェルスクリプト を解釈し、実行するインタプリタ。
シェルは GUI を持っていないので、私たちは端末エミュレータが提供するインターフェース(CLI)を介してシェルを利用している。
Windows の PowerShell のように、シェルが端末エミュレータと一体になっているものもある。
具体的には Bash、Zsh、sh などのプログラムがシェルである。
種類 | 特徴 |
---|---|
Bash | Unix 系システムで広く使用される |
Zsh | 高度な機能とカスタマイズ性を持つ |
sh | 古い Unix シェルの一つ |
コマンドライン(cmd.exe ) |
Windows コンソールホスト上で動作 MS-DOS 由来のコマンドが多い |
Power Shell | コマンドラインの後継 GUI を持つため、端末エミュレータでもある オブジェクト指向 |
ログイン直後に起動されるシェルは ログインシェル と呼ばれる。
端末エミュレータを介してシェルに渡されたコマンドは、シェルによって起動された 子プロセス 上で実行される。
$ コマンド
シェルが動作しているプロセス上でコマンドを実行したい場合には、$ source
や $ .
などのコマンドを使用する。
$ source コマンド
$ . コマンド
Bash / $ bash
Bourne Again Shell
Unix 系システムで広く使用されている標準シェル。POSIX 規格に準拠しており、ほとんどの Unix 系システムで動作する。
Bash は $ bash
コマンドで起動できる。
$ bash
私の環境は macOS なので、デフォルトでは Zsh がログインシェルになっている。
特定のシェルとの対話(ログイン ~ ログアウトまで)を セッション と表現することがあり、Zash が Bash を起動した場合、Bash による新しいシェルセッションが開始されることとなる。
$ echo $0 # ログイン中のシェルを確認する
-zsh
$ bash
The default interactive shell is now zsh.
To update your account to use zsh, please run `chsh -s /bin/zsh`.
For more details, please visit https://support.apple.com/kb/HT208050.
bash-3.2$ # Bash のシェルセッションが開始される
起動した Bash は $ exit
で終了できる。
シェルとの対話(セッション)を開始せずに、特定のスクリプトを実行させることもできる。
$ bash スクリプト
Zsh / $ zsh
Z Shell
高度な機能とカスタマイズ性を持つシェル。Bash と同様に POSIX 規格に準拠している。
近年の macOS のデフォルトシェル。
$ bash
と同様に、新しいシェルセッションを開始することができる。
$ zsh
$ zsh スクリプト
sh
Bourne Shell
古くから存在するUnixシェルの一つで、他の多くのシェル(Bash、Zsh など)の基礎となっている。
「sh」と言う用語は、シェルスクリプトやコマンドを示すための一般的な総称として使われることがあり、Bash、Zsh、sh で記述されたスクリプトファイルの拡張子には .sh
が使用される。
POSIX
Portable Operating System Interface
IEEE によって策定される Unix 系 OS 間での互換性を保つための規格。
開発者目線では、POSIX 規格に従って開発することでプログラムが異なる OS 間で移植可能になる。また、Windows OS は POSIX には準拠していない(WSL といった技術は提供されている)。
さまざまなサブ規格に分かれている。
プロンプト $
/ %
/ #
prompt=促す
端末エミュレータが提供する CLI において、ユーザに対してコマンドの入力を促す文字列や記号のこと。
シェルが表示させている。
プロンプトが表示中は、コマンド入力を受付中であり、プロンプトが表示されていない間は何らかのプロセスが実行中であることを意味する。
シェルによって特定の記号が特別な意味を持つ場合がある。
記号 | 意味 |
---|---|
$ |
一般ユーザ としてログイン中であることを示す |
# |
スーパーユーザ(管理者)としてログイン中であることを示す |
% |
Zsh 等で利用される |
プロンプトとして表示される文字列は ビルトインシェル変数の $PS1
、$PS2
でカスタマイズすることができる。
カーネル
Kernel
以下に挙げられるようなシステムの基幹となる制御を行う OSの中核 部分を担うソフトウェア。
ハードウェアとソフトウェアの橋渡し的な役割を持つ。
通常、アプリケーション(プロセス)は、カーネルから提供されるインターフェースを介してのみ、デバイス(ハードウェア)へのアクセスが許されている。
この制限によって、デバイスに複数のプロセスが同時にアクセスする場合でも、カーネルが競合するアクセス要求を調停するため、アプリケーション間でリソースの競合が起きない仕組みになっている。
カーネルがアプリケーションに提供するインターフェースや、機能を利用するために呼び出す命令または関数を システムコール 、スーパーバイザコール(SVC:supervisor call)という。このインターフェースは、ハードウェアの仕様の違いに依存しないように抽象化されている。
カーネルモード / ユーザモード
CPU の動作モードには、カーネルモード と ユーザモード がある。
カーネルモードは、その名の通りカーネルのプロセスが動作したり、デバイスドライバなどのプロセスが動作したりするモードであり、 特権モード とも呼ばれる。
カーネルモードの CPU は、メモリ、I / O デバイスなどのハードウェアリソースに、制限なくアクセスを行うことができる。そのため、カーネルモードで不正な操作が行われたりバグが発生すると、メモリが破壊されたりデバイス動作が停止するといった、システム全体に影響が出る。
一方ユーザモードは、通常のアプリケーションプログラムが動作するモードであり、直接ハードウェアにアクセスを行うことができない。ユーザモードで動作するプロセスは、カーネルの提供するシステムコールを介してハードウェアにアクセスする。
システムコール
カーネルから提供される、プロセスがカーネルの特権的な機能を呼び出すためのインターフェース。
- ファイル操作:
open
,read
,write
- プロセス管理:
fork
,exec
,kill
- ネットワーク通信:
socket
,connect
システムコールは、ユーザモード で動作中の CPU をカーネルモードへ遷移させる手段でもある。
システムコールの実行が終了すると、CPU はカーネルモードから再びユーザモードに戻ってプロセスの実行を継続する。
システムコールを呼び出すことができるプログラミング言語は複数ある。
- C言語
- アセンブリ言語
- Rust
- Go
- Python
- C++
- Perl
- Ruby
- AssemblyScript / WebAssembly
C言語やアセンブリ言語は、OS やカーネル開発において主要言語として採用されることが多い。一方、Python や Perl などはシステムコールを直接呼び出す用途ではなく、ラッパーやモジュール経由で利用することが多い。
C言語には、glibc
と呼ばれる 標準Cライブラリ が存在し、この中にはシステムコールを内部的に呼び出すラッパー関数が含まれている。アセンブリ言語は直接システムコールを呼び出すことができるものの、アーキテクチャ ごとに存在するシステムコールを環境に応じて呼び分ける必要がある。C言語では glibc
のようなラッパー関数がアーキテクチャごとの違いを吸収するため、呼び出し側はその違いを意識する必要がない。
例外
プロセスがシステムコールを発行すると、CPU において 例外 が発生する。
この例外をトリガーにして、CPU は ユーザモード から カーネルモード へ遷移し、システムコールの処理を行う。
システムコールの処理が終了すると、CPU は再びユーザモードに戻り、プロセスを継続する。
標準Cライブラリ
C言語に標準で付属しているライブラリ。
システムコール のラッパー関数が含まれ、glibc
(GNU C Library)とも言う。
- 入出力操作(
printf
,scanf
) - メモリ管理(
malloc
,free
) - ファイル操作(
fopen
,fread
,fwrite
) - システムコールのラップ(
open
,read
,write
)
システムコール | 標準Cライブラリのラッパー関数 | 説明 |
---|---|---|
open |
open |
ファイルを開く |
read |
read |
ファイルやデバイスからデータを読み取る |
write |
write |
ファイルやデバイスにデータを書き込む |
close |
close |
ファイルを閉じる |
コマンド
シェルに対する命令。端末エミュレータ への入力を介して実行する。
コマンドの実体は実行可能ファイルであり、実行可能ファイルにはバイナリ形式とスクリプト形式(テキスト)がある。
コマンドの実体はバイナリ形式、もしくはテキスト形式の実行可能ファイル
その他、以下のような形式もある。
実行可能ファイル(バイナリ形式)
バイナリ形式の実行可能ファイル。
バイナリ形式とは、「0」「1」の二進数で表現されたデータ形式のこと。
実行可能ファイルとは、実行権限 のあるファイルのこと。
バイナリ形式の実行可能ファイルは、具体的には C 言語などのコンパイル形式のプログラミング言語で記述されたプログラムをコンパイルしたものを指す。コンパイル形式の言語にはその他 C++、Rust、Go などがある。
バイナリ形式の実行可能ファイルをコマンドとして実行した場合、そのプロセスは 呼び出したシェルとは別プロセスとして実行される。
この形式のコマンドの代表例には $ ls
、$ grep
、$ cat
などがある。
Linux にはバイナリ形式の実行可能ファイルに拡張子をつけない習慣があり、上記のコマンドの実体はそれぞれ、/bin/ls
、/usr/bin/grep
、/bin/cat
などの拡張子の付かないファイルとして存在している。
私を含む Linux の初学者は、コマンドを使い始めた頃、使っているコマンドの実体がファイルであることを意識しないと思う。それは多分、バイナリ形式の実行可能ファイルは絶対パスで実行することもできるし、ファイル名だけでも実行することができるからだと思う。
$ /bin/ls
$ ls
なぜファイル名を入力しただけで、シェルがファイルを探し当てることができるのかについては、環境変数 $PATH
の存在を理解する必要がある。
$PATH
には通常以下のような値が設定されている。
$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
$ ls
が実行された時、シェルはまずこのリスト内から ls
ファイルがないかを探している。
もし環境変数 $PATH
に /bin
が設定されていない場合には、シェルは ls
ファイルを見つけることができず、ファイル名だけでコマンドを実行することはできない。一方で、ビルトインコマンドは $PATH
を使用しないので、設定がなくても実行することができる。
※ 正確には下記の順に検索が行われる
- エイリアス
- ビルトインコマンド
- 環境変数
$PATH
なお、$PATH
にはカレントディレクトリを含めることができないため、カレントディレクトリ上の実行可能ファイルを実行するには ./
に続けてファイル名を指定する必要がある(.
はカレントディレクトリを表す)。
$ ./ファイル名
また「ビルトインコマンド」は 内部コマンド と呼ばれることがあるのに対して、「バイナリ形式の実行可能ファイル」を 外部コマンド と呼ばれる。
実行可能ファイル(スクリプト形式)
スクリプトファイルは実行権限を付与することで、スクリプト としてシェルから実行することができる。
コマンドとしてファイル名だけで実行させるためには、スクリプトファイルに読み取り権限(r
)と 実行権限(x
) を付与する必要がある(バイナリ形式のファイルの場合、実行権限のみで良い)。
$ ./スクリプトファイル # 読み取り権限と実行権限が必要
一方で、$ bash
や $ source
の引数に渡して実行する場合には、読み取り権限(r
)だけで実行できる。
$ bash スクリプトファイル
$ source スクリプトファイル
$ . スクリプトファイル
スクリプトの記述方法については こちら。
ビルトインコマンド
シェルに組み込まれたコマンド。内部コマンド と呼ばれることもある。
シェルによって直接実行されるため、呼び出したシェルのプロセス内で実行される。
代表的なものに $ cd
、$ pwd
、$ echo
、$ alias
、$ export
などがある。
$ type cd
cd is a shell builtin
バイナリ形式の実行可能ファイル とは異なり、環境変数 $PATH
を気にする必要がない。
関数
シェルスクリプトで定義した関数はコマンドのように実行することができる。
関数は $ function
によって定義し、$ unset
で削除することができる。
$ function say_hello() { echo "hello world"; }
$ say_hello
hello world
シェルスクリプトを実行した場合に子プロセスが生成されるのに対して、関数を実行した場合には子プロセスは生成されない。
エイリアス
既存のコマンドには エイリアス と呼ばれる「別名」をつけて実行することができる。
$ which
$ which コマンド名
$ which ls
/bin/ls
※ $PATH
に記載がないディレクトリにあるコマンドは表示されない
$ whereis
$ whereis コマンド名
$ whereis ls
ls: /bin/ls /usr/share/man/man1/ls.1
$ whatis
コマンドのマニュアルページの説明部分を 1 行で簡易表示させる。
$ whatis コマンド名
マニュアルをすべて表示したい場合には $ man
を使う。
表示される (数字)
はマニュアルのセクション番号を表す。
$ man ls
ls (1) - list directory contents
$ type
$ type コマンド名
$ type ls
ls is /bin/ls
$ type cd
cd is a shell builtin
$ kill
コマンドのように、ビルドインコマンドと実行可能ファイルの両方を持つものもある。
$ command
ビルトインコマンド と 外部コマンド を使い分ける際に利用される。
$ command
自体はビルトインコマンド。
同じ名前のコマンドにビルトインコマンドと外部コマンドがある場合、通常はビルトインコマンドが優先して使用される。
このようなとき、$ command
を利用することで明示的に外部コマンドを実行することができる。
$ command コマンド
他にも、外部コマンドと同名の エイリアス が設定されている場合に、エイリアスを無視して外部コマンドを優先して実行させることができる。
$ alias
登録済みエイリアスは $ alias
で表示することができる。
$ alias
新たにエイリアスを定義する際は、次のようにエイリアス名とコマンド名を =
で指定する。
$ alias エイリアス名=コマンド
$ alias hello='echo "hello world"'
$ hello
hello world
セミコロン ;
を使うと、複数のコマンドを集約させることもできる。
$ alias hello='echo "hello";echo "bye"'
$ hello
hello
bye
引数にエイリアス名を指定すると、エイリアスにしたコマンドを表示することができる。
$ alias エイリアス名
$ alias hello
hello='echo "hello world"'
$ alias
コマンドで登録したエイリアスは、現在のシェルセッションでのみ有効 であるため、永続的なエイリアスを登録したい場合、シェルの 環境設定ファイル に定義を追加する。
Bash を使用している場合 ~/.bashrc
という環境設定ファイルがシェル起動時に読み込まれているため、このファイルに以下の1行を追加しておくことで永続的なエイリアスを追加することができる。
alias hello='echo "hello world"'
編集した ~/.bashrc
ファイルは端末エミュレータを再起動するか、$ source
コマンドを使って、シェルに再読み込みさせることができる($ source
と $ bash
の違い )。
$ source ~/.bashrc
$ unalias
$ unalias エイリアス名
$ function
$ function 関数名() { 処理; }
$ 関数名() { 処理 }
※ function
で定義する場合、処理の末尾にはセミコロン ;
を記載する
$ history
$ history
履歴番号 コマンド
$ !履歴番号
とすることで、指定した履歴コマンドを再度実行させることができる。
$ !履歴番号
$ !!
$ !検索ワード
Bashの場合 ~/.bash_history
にコマンド履歴が保存され、保存できる履歴の最大数はビルトインシェル変数 $HISTSIZE
、$HISTFILESIZE
で設定できる。
また、Ctrl
+ R
の同時押しでコマンド履歴を検索することもできる(reverse-i-search:逆順インクリメンタル検索)。
$ # Ctrl + R を押す
bck-i-search: _
検索モードからは Ctrl
+ G
もしくは Esc
で戻ることができる。
$ # ←ここに検索ワードを入力する
bck-i-search: _
検索にヒットした履歴は、再び Ctrl
+ R
を押すことでさらに過去のヒット結果に移ることができる。
履歴の位置は保存されるため、Ctrl
+ G
で検索を終了した時、↑
や ↓
を押すと、ヒットした履歴の位置からの表示になる。
$ eval
引数とした渡された文字列をコマンドとして実行するためのコマンド。
$ eval "コマンド"
$ apropos
$ apropos キーワード
$ man
manual
コマンドのマニュアルページを表示する。
$ man コマンド名
表示されたマニュアルは Q
キーで終了できる。
実際には「コマンド」のマニュアルだけでなく、設定ファイル、ライブラリ、システムコールなどのマニュアルページも検索、表示することができる。
$ man 検索ワード
$ man -f 検索ワード
$ man -k 検索ワード
マニュアルページには セクション と呼ばれる分類があり、セクション番号があらかじめわかっている場合、番号を指定して検索を行うことができる。
$ man セクション番号 検索ワード
セクション | 内容 |
---|---|
1 | 一般コマンド(一般ユーザが使用する) |
2 | システムコール(カーネルが提供する API) |
3 | 標準Cライブラリ |
4 | デバイスファイル |
5 | 設定ファイル |
6 | ゲーム、スクリーンセーバー |
7 | その他 |
8 | システム管理コマンド(root ユーザ向け) |
9 | Linux 独自のカーネル用ドキュメント |
~/.bash_hisotry
$ history
が参照するコマンドの実行履歴が格納されたファイル。
履歴情報は シェルの起動時
に ~/.bash_hisotry
から読み出される。
また シェルにログイン中
もしくは セッション中
は、シェルプロセス内のメモリ上に保持され、コマンド実行の都度 ~/.bash_hisotry
へ書き込まれているわけではない。
最後にログアウト、セッション終了時に ~/.bash_history
へ再び書き込まれる。
この挙動は「複数のタブを開いて操作」した場合に、複数のタブにまたがって実行したコマンド履歴が、時系列順に表示されない 現象を引き起こす。
/usr/share/man
$ man
が参照するディレクトリ。
Linux ディストリビューションに含まれる、パッケージのマニュアルドキュメントの格納ディレクトリ。
/usr/local/share/man
$ man
が参照するディレクトリ。
Linux ディストリビューションに含まれない、ユーザが後からインターネット経由などで追加したパッケージのドキュメント格納ディレクトリ。
コマンド置換
$()
でコマンドを囲うと、コマンドの実行結果を文字列に展開して、別のコマンドの引数として渡すことができる。
古い記法としてバックコーテーション ``
を利用した方法もあるが、可読性が低くなるため $()
の使用が推奨されている。
$ echo $(コマンド)
$ echo `コマンド` # ` はバックコーテーション
文字列中の変数の展開 同様に文字列内でも展開することができるが、シングルコーテーション内では展開されないため注意。
$ echo "ls: $(ls)"
$ echo "ls: `ls`"
$ echo '$(ls)' # コマンド置換されない
'
シングルコーテーションで囲った文字列中のコマンドは展開されない
複数のコマンドを続けて実行する
;
で複数のコマンドを続けて実行させることができる。コマンド実行結果にかかわらず、後続のコマンドは実行される。
$ コマンド1; コマンド2; コマンド3
&&
では、コマンドが正常終了した場合のみ、後続のコマンドが実行される。
$ コマンド1 && コマンド2 && コマンド3
||
では、コマンドが異常終了した場合のみ、後続のコマンドが実行される。
$ コマンド1 || コマンド2 || コマンド3
()
で複数のコマンドをまとめることもできる。
$ (コマンド1; コマンド2; コマンド3) && コマンド4
複数行のコマンド入力
複数行のコマンドを入力したい場合、行末にバックスラッシュ \
を記述する。
$ echo \
$ "hello world"
hello world
一時的にエイリアスを無効化する
既存のコマンドと重複するエイリアスが設定されている場合、通常はエイリアスの方が優先される。
/
をコマンドの前につけることで、エイリアスを一時的に無効化することができる。
$ /コマンド
複数のタブにまたがるコマンド履歴 / $PROMPT_COMMAND
~/.bash_hisotry
の挙動は「複数のタブを開いて操作」した場合に、複数のタブにまたがって実行したコマンド履歴が、時系列順に表示されない現象を引き起こすことがある。
これは、コマンド履歴がタブごとに保持され、後から閉じたタブが先に閉じたタブが書き込んだ履歴を上書きするためである。
厳密にはコマンド履歴はシェルのプロセスごとに保持されている。タブが異なれば、起動しているシェルプロセスも異なるため、コマンド履歴は結果的にタブごと別々に保持されていることとなる。
コマンド履歴を即時反映させたい場合には $PROMPT_COMMAND
に以下を追加する。これにより、コマンド実行の度に ~/.bash_history
が更新させることができる。
$ export PROMPT_COMMAND="history -a; history -n"
$ hostory -a
$ history -n
変数
シェル変数
ログイン中のシェルセッションでのみ有効な変数。
親プロセスから子プロセスへ引き継がれない。
$ 変数名=値
$ $変数名
$ hello=こんにちは
$ echo $hello
こんにちは
ビルトインシェル変数
シェルであらかじめ宣言されている変数。
ビルトインシェル変数 | 説明 |
---|---|
$0 |
実行中のシェルの名前、もしくはコマンド名やスクリプトファイルのパス 【覚え方】0 番目の引数→起動名 |
$1 ,$2 ,$3 ... |
シェルスクリプト内もしくは関数内で、渡された引数が順に格納される(1番目は $0 ではなく $1 )【覚え方】n 番目の引数 |
$* ,$@
|
シェルスクリプト内で、スクリプトに渡されたすべての引数を取得する際に使用$* :一つの文字列として格納$@ :文字列の集合として格納(スペース区切り)【覚え方】全部の引数 |
$# |
シェルスクリプト内で、スクリプトに渡された引数の数 【覚え方】引数の数 |
$? |
直前の実行コマンドの終了ステータス 成功の場合は 0 、失敗の場合は 0 以外の値が自動的に格納される【覚え方】うまくいった ?
|
$$ |
実行中のシェル自身のプロセスID |
$! |
最後にバックグラウンドで生成されたコマンドのプロセスID |
$PS1 |
プロンプトとして表示する文字列の定義(prompt string) |
$PS2 |
セカンダリプロンプト(複数行入力時の表示)として表示する文字列の定義 |
$PROMPT_COMMAND |
プロンプトが表示される直前に実行されるコマンド |
$HISTFILE |
コマンド履歴を保存するファイルのパス デフォルト値: ~/.bash_history
|
環境変数
親プロセスから子プロセスに引き継がれる変数。
環境変数を介して情報を参照することで、シェルまたはシステム全体で情報を共有することができる。
システム全体で利用する環境変数は、シェル起動時に実行される /etc/bash.bashrc
ファイル(Bash の場合)にて $ export
を実行する。
ユーザ固有の環境変数は ~/.bashrc
にて $ export
する。
ただし、これらの設定ファイル はシェルの起動時にしか読み込まれないため、シェル起動後にファイルを編集した場合は $ source
コマンドによって再読み込みさせる必要がある。
また、スクリプト内でも $ export
を使って環境変数を設定することはできるが、その環境変数はスクリプト内でのみ有効であり、スクリプトが終了すると使用することはできない。つまり、変数は親シェルに対して反映させることはできない。
もしスクリプトから呼び出し元のシェル(親プロセス)でも有効な環境変数を設定したい場合、$ source スクリプト
という形で、スクリプトを現在のシェル上で実行する必要がある。
環境変数 | 説明 |
---|---|
$PATH |
実行可能ファイル の検索パス 複数のパスが : で区切られた文字列として格納される |
$HOME |
ユーザのホームディレクトリのパス チルダ ~ でも取得可能 |
$PWD |
現在の作業ディレクトリ |
$OLDPWD |
$ cd で移動する前の作業ディレクトリ |
$SHELL |
現在使用されているシェルのパス(/bin/bash 、/bin/zsh など) |
$LANG |
ロケール |
カーネル変数
カーネルの動作を制御するための設定値。
カーネル変数の変更は、動作中のカーネルに対して即時反映される。
$ sysctl
を使用して確認、変更することができる。
また、カーネル変数は /proc/sys/
ディレクトリ配下のファイルを介して、確認、変更することもできる。
$ sysctl -a # すべて表示
$ sysctl 変数名
$ cat /proc/sys/ファイル名
$ sysctl -w カーネル変数名=値
$ echo 値 > /proc/sys/ファイル名
カーネル変数の変更を永続的に行いたい場合、/etc/sysctl.conf
を編集する必要がある。
カーネル変数名 = 値
カーネル変数 | パス | 説明 |
---|---|---|
net.ipv4.ip_forward |
/proc/sys/net/ipv4/ip_forward |
パケットのフォワーディング(ルータ機能の有効化) |
net.ipv4.icmp_echo_ignore_all |
/proc/sys/net/ipv4/icmp_echo_ignore_all |
$ ping への反応を無効化 |
net.ipv4.conf.all.rp_filter |
/proc/sys/net/ipv4/conf/all/rp_filter |
逆方向パケットフィルタの設定(IP スプーフィング対策) |
vm.swappiness |
/proc/sys/vm/swappiness |
スワップ使用の閾値。 低いほど物理メモリが優先される |
fs.file-max |
/proc/sys/fs/file-max |
システム全体の最大オープンファイル数 |
$ set
実行中のシェル環境内で定義された全ての以下変数を表示する。
- シェル変数
- ビルトインシェル変数
- 環境変数
$ set
-o
/ +o
オプションによってシェルの機能を有効化したり無効化することができる。
-
が有効化、+
が無効化であり、個人的には直感に反している気がしたが、古来の Bash の文化、慣習らしい。
$ set -o 対象機能
$ set +o 対象機能
対象機能 | 説明 |
---|---|
errexit |
コマンドがエラーを返した時に、即座にスクリプトを終了する |
nounset |
未定義の変数を使用した場合にエラーを発生させる |
xtrace |
実行するコマンドを表示(スクリプトのデバッグ用) |
verbose |
コマンドの内容をそのまま表示 |
noexec |
コマンドの実行をせずに構文チェックのみを行う |
現在の設定を確認することもできる。
$ set -o
実行結果
$ set -o
allexport off
braceexpand on
emacs on
errexit off
errtrace off
functrace off
hashall on
histexpand on
history on
ignoreeof off
interactive-comments on
keyword off
monitor on
noclobber off
noexec off
noglob off
nolog off
notify off
nounset off
onecmd off
physical off
pipefail off
posix off
privileged off
verbose off
vi off
xtrace off
現在の設定を復元するためのコマンド一覧を表示することもできる。
$ set +o
実行結果
$ set +o
set +o allexport
set -o braceexpand
set -o emacs
set +o errexit
set +o errtrace
set +o functrace
set -o hashall
set -o histexpand
set -o history
set +o ignoreeof
set -o interactive-comments
set +o keyword
set -o monitor
set +o noclobber
set +o noexec
set +o noglob
set +o nolog
set +o notify
set +o nounset
set +o onecmd
set +o physical
set +o pipefail
set +o posix
set +o privileged
set +o verbose
set +o vi
set +o xtrace
$ unset
シェル変数、関数定義を削除する。
$ unset 変数名
$ unset 関数名
$ declare
変数に特定の属性(型や制約)を設定することができる。
$ declare 変数名=値
オプション | 説明 |
---|---|
-i |
変数を整数型に制限する 整数以外の値を代入すると 0 扱いになる |
-r |
読み取り専用の変数にする(再代入不可) |
-x |
環境変数としてエクスポートする($ export と同じ) |
-f |
定義された関数を一覧表示する |
-F |
定義された関数名を一覧表示する |
$ export
シェル変数を環境変数として設定する。環境変数となった変数は、子プロセスに引き継がれる。
$ export 定義済みシェル変数名
$ hello="こんにちは"
$ export hello
シェル変数を定義すると同時に環境変数として宣言することもできる。
$ export 環境変数名=値
$ export PATH="/some/directory:$PATH"
この時の末尾の :$PATH
は、既存の $PATH
の先頭に追記をするためのもの。誤って上書きしてしまわないよう注意が必要。
設定ファイルに $ echo
とリダイレクト演算子 >>
を利用して追記することもできる。
$ echo 'export PATH="/some/directory:$PATH"' >> ~/.bashrc
$ printenv
$ printenv
$ printenv 環境変数名
$ env
環境変数を表示したり、一時的な環境変数を設定しながら別のコマンドを実行する。
単に $ env
とした場合、$ printenv
と同様に環境変数の一覧が表示される。
$ env
下記のように記述すると、現在のシェルプロセスには影響を与えず子プロセス内でのみ有効な環境変数を設定することができる(こちら を参照)。
$ env 環境変数名=値 コマンド
$ env -i コマンド
変数の展開
変数を展開したい場合は、$変数名
もしくは ${変数名}
とする。
コマンドの引数、条件式、配列展開などシェルスクリプトのさまざまな場所で適用することができる。
$ echo $変数名
$ echo ${変数名}
文字列リテラル中でも使用することができる。
$ echo "hello $変数名"
$ echo "hello ${変数名}"
ただし文字列リテラルで使用する場合、'
シングルコーテーションで囲った文字列中の変数は展開されないため注意)
'
シングルコーテーションで囲った文字列中の変数は展開されない
特に、パスのようにスペースを開けずに変数を使用したい場合は ${変数名}
を使用する。
$ hello=こんにちは
$ echo $hello
こんにちは
$ echo "$hello"
こんにちは
$ echo "$hello world"
こんにちは world
$ echo "$helloworld" # 変数 helloworld が未定義のため、何も出力されない
$ echo "${hello}world" # 変数に続いてスペースなしで文字列を使用する場合
こんにちはworld
子プロセスの環境変数を設定する
コマンドを実行する際に、変数宣言をコマンドの前に置くことで、実行されるコマンド(子プロセス)でのみ有効な環境変数を設定することができる。
これにより、現在のシェルプロセスには影響を与えずに環境変数を利用することができる。
$ 環境変数名=値 コマンド
$ env
を利用した場合も同じ。
$ env 環境変数名=値 コマンド
終了ステータス / $?
直前の実行コマンドの終了ステータス。0
~ 255
が使用可能。
- 成功:
0
- 失敗:
0 以外
自作のスクリプトで終了ステータスを呼び出し元に返すには、$ exit
コマンドを使用する。
exit 0 # 正常終了(成功)
exit 1 # 異常終了(エラーなど)
これを利用して、異常が発生したらスクリプトを終了させることができる。
if [ $? != 0 ]; then
exit 1;
fi
エラー発生後に $ echo
コマンドで $?
を確認した場合、$ echo
コマンドの成否が $?
に再代入される点に注意。
$ cd not_exixts_directory
cd: no such file or directory: not_exixts_directory
$ echo $? # $? には cd コマンドの終了ステータスが格納されている
1
$ echo $? # $? には直前の echo コマンドの終了ステータスが格納されている
0
$PS1
/ $PS2
コマンドプロンプト として表示される文字列の設定。
以下の特殊文字(エスケープシーケンス)を使用することができる。
特殊文字 | 意味 |
---|---|
\u |
ユーザ名 |
\h |
ホスト名(/etc/hostname で設定) |
\w |
現在の作業ディレクトリ |
\$ |
ユーザの種類($ :一般ユーザ、# :root ユーザ) |
\s |
シェルの名前 |
\v |
シェルのバージョン |
セカンダリプロンプトは、コマンドを複数行にまたがって入力 する場合に表示される。
$ コマンド \
セカンダリプロンプト
デフォルトでは $PS1='[\u@\h:\w]\$'
、$PS2='>'
のようになっていることが多い。
ログインシェル / 対話型シェル
シェル は役割の違いによって ログインシェル や 対話型シェル と呼び分けられることがある。
ログインシェル
ログインして最初に起動されるシェル。
ログインを必要とするので、シェル起動時にユーザアカウントの パスワードの入力が要求される。
ログインシェルには以下がある。
- 仮想コンソール で ログイン したとき
-
$ ssh
で ログイン したとき$ ssh ユーザー名@ホスト
- 明示的にログインシェルを起動したとき
$ bash --login
- ログインユーザを指定してシェルを起動した時
-
$ su - ユーザー名
($ su
だけだとログインシェルにならない) - 厳密には「ログイン後、最初に起動されるシェル」ではないが、設定ファイルの読み込みの挙動がログインシェルとしての振る舞いを見せる
-
ログインシェルでは、起動(ログイン)時は以下の順に 設定ファイル が読み込まれる。
/etc/profile
↓
~/.bash_profile
↓
(~/.bash_login)
↓
(~/.profile)
終了(ログアウト)時は ~/.bash_logout
が読み込まれる。
ログインシェルを Bash にするのか Zsh にするのかの設定は、/etc/passwd
で行うことができる。
非ログインシェル
「ログインシェルではないが、対話型シェルであるシェル」を 非ログインシェル と呼ぶ。
ログインを行わずにシェルが起動されるため、ユーザアカウントのパスワードが要求されない。
非ログインシェルには以下がある。
- ターミナルアプリを開いたとき
- Bash を
--login
オプションなしで起動したとき$ bash
非ログインシェルは対話型シェルの一つなので、起動時に ~/.bashrc
が実行され、その後、プロンプト表示によってインタラクティブなコマンド入力を待つ状態になるものの、ログインシェルではないため ~/.bash_profile
は読み込まれない。
ただし、環境変数は親シェル(ログインシェル)から引き継がれる。
対話型シェル
ユーザーが直接コマンドを入力できるシェルのこと。インタラクティブシェル とも呼ばれる。
大きな特徴として、プロンプトが表示され、ユーザーの入力を待つという点がある。
対話型シェルには以下がある。
- ログインシェルとして Bash を開いたとき
- ログインシェルは基本的に対話型シェル でもある
$ ssh ユーザー名@ホスト
$ su - ユーザー名
$ bash --login
- ターミナルアプリを開いたとき
- ログインシェルではないが、対話型シェル である状態
- 明示的に対話型シェルを起動したとき
-
$ bash -i
(interactive)
-
対話型シェルでは起動の度に ~/.bashrc
が実行される。~/.bashrc
内では /etc/bash.bashrc
が呼ばれることが多い。
非対話型シェル
スクリプトを実行するだけのシェルを 非インタラクティブシェル(非対話型シェル) と呼ぶことがある。
非インタラクティブシェルには以下がある。
- スクリプトが実行されるとき
$ bash myscript.sh
- シェルスクリプトが シバン(
#!/bin/bash
)で実行されたとき -
$ bash -c 'コマンド'
でコマンド実行するとき
非インタラクティブシェルでは、 ~/.bashrc
は自動で読み込まれない。
そのため、非対話型シェルで実行させるスクリプト内で、エイリアスや関数を利用したい場合、$ source ~/.bashrc
もしくは $ . ~/.bashrc
を実行する必要がある。
$ chsh
change shell
$ chsh
$ chsh -l
$ chsh --list-shells
$ chsh -s /bin/zsh
指定するシェルは /etc/shells
に記載されているものである必要がある。また $ chsh
の内部的には /etc/passwd
にあるユーザー情報の shell
フィールドが書き換えられている。
またログインシェルを変更した場合、次回ログインから有効となり、現在のセッションには影響しない。
/etc/shells
ログインシェルとして使用可能なシェルの一覧が記載されたファイル。
/bin/sh
/bin/bash
/bin/zsh
/usr/bin/fish
設定
シェルには Bash や Zsh などの種類ごとに設定ファイルが存在する。
各設定ファイルは スクリプト形式 で記述されており、それぞれ実行されるタイミングが異なる。そのため、実行されるタイミングに合わせて必要な環境設定を行うことができる。
各設定ファイルには 読み取り権限 があれば良い。
ログインシェル と 対話型シェル で実行されるファイルが異なる。
起動順序は以下の通り。最初に以下のパターンを頭に入れておくと理解しやすい。
システム全体に適用される /etc/ の設定ファイル
↓
ユーザ単位で適用される ~/ の設定ファイル
↓
(上記ファイルが存在しない場合に適用される設定ファイル)
/etc/profile
↓
~/.bash_profile
↓
(~/.bash_login)
↓
(~/.profile)
/etc/bash.bashrc
↓
~/.bashrc
↓
(/etc/bashrc)
/etc/profile
- 対象:ログインシェル
- 読み込まれるタイミング:OS へのログイン時
- 主な用途:システム全体の環境設定
/etc/bash.bashrc
bash run commands
- 対象:対話型シェル(ログイン・非ログインに関わらず実行される)
- 読み込まれるタイミング:Bash の起動時
- 主な用途:システム全体の対話型シェル設定
- 全てのユーザで共有される
- Debian系(Ubuntu、Debian)で利用される
- ログイン時にも実行したい場合には、
/etc/profile
内で$ source /etc/bash.bashrc
もしくは$ . /etc/bash.bashrc
を実行する必要がある
/etc/bashrc
bash run commands
- 対象:対話型シェル
- 読み込まれるタイミング:Bash の起動時
- 主な用途:システム全体の対話型シェル設定
- ユーザごとにファイルが存在する
-
~/.bashrc
から呼ばれ、間接的に実行されるのが一般的 - Red Hat系(CentOS、Fedora、RHEL)で利用される
~/.bash_profile
- 対象:ログインシェル
- 読み込まれるタイミング:OS へのログイン時
- 主な用途:ユーザーごとの環境設定(
Welcome ${whoami}!
のようなログイン時にだけ表示するメッセージなど)- ユーザごとにファイルが存在する
- ログインシェルにおいても対話型シェルの設定を利用するために、
~/.bash_profile
内で$ source ~/.bashrc
もしくは$ . ~/.bashrc
するのが一般的
~/.bash_login
- 対象:ログインシェル
- 読み込まれるタイミング:OS へのログイン時
-
~/.bash_profile
が存在しない場合にのみ、実行される- ユーザごとにファイルが存在する
~/.profile
- 対象:ログインシェル
- 読み込まれるタイミング:OS へのログイン時
-
~/.bash_profile
も~/.bash_login
のどちらも存在しない場合にのみ、実行される- ユーザごとにファイルが存在する
~/.bashrc
bash run commands
- 対象:対話型シェル
- 読み込まれるタイミング:Bash の起動時
- ログインシェルの起動時に
~/.bach_profile
内でも呼び出されるので、結果的に、シェルの起動時は必ず実行される
- ログインシェルの起動時に
- 主な用途:ユーザーごとの対話型シェル設定(エイリアス の設定など)
- ユーザごとにファイルが存在する
~/.bash_logout
- 対象:ログインシェル
- 読み込まれるタイミング:OS からのログアウト時(
$ exit
時) - 主な用途:一時ファイルを削除したり、画面をクリアするなど
- 設定ファイルがなければ実行されない
- ユーザごとにファイルが存在する
$ shopt
Shell Options
Bash のオプションを設定するためのビルトインコマンド。
$ shopt
オプション名を引数に渡すと、特定のオプションの状態を確認することができる。
$ shopt オプション名
$ shopt -p # s(set)で表示されたものは有効。u(unset)で表示されたものは無効。
現在のシェルセッションで使用中のシェルがログインシェルであるかどうかは、login_shell
オプションを確認することで確認できる。
$ shopt login_shell # on ならログインシェル
login_shell on
$SHELL
ビルトインシェル変数 $SHELL
には、ユーザーのログイン時に設定されたデフォルトのシェルのパスが格納されている。
表示されたシェルは、現在動作中のシェルとは限らない。
$ echo $SHELL
/bin/zsh
$0
ビルトインシェル変数 の $0
には、現在実行中のシェルまたはスクリプトの名前が格納されている。ログインシェルの場合、先頭に -
が付く。
$ echo $0
-bash
$ source
/ $ .
指定したシェルスクリプトを現在起動しているシェルのプロセス上(現在と同じシェル環境)で実行する。
$ source スクリプトファイル
環境設定ファイル を編集した際に、シェルを再起動することなく反映させるために使用される。
$ source ~/.bashrc
$ source
コマンドで読み込んだスクリプトは、現在起動しているシェルのプロセス内で実行される ため、環境変数やエイリアスの設定を、起動中のシェル環境に即時適用させることができる。
またドット $ .
もコマンドであり $ source
と同じ機能を持つ。
$ . スクリプトファイル
$ source
と $ bash
との違い
$ source
と $ bash
はどちらも引数としてスクリプトを渡して実行させることができるが、スクリプトが実行される環境には大きな違いがある。
まず、$ source
は 呼び出したシェルと同じプロセス上で実行される。
$ source スクリプトファイル
ここで言う「呼び出し元のシェル」とは、私たちが入力したコマンドを受け付けるために
一方、$ bash
は呼び出し元のシェルが新しいシェルプロセス(子プロセス)を起動し、渡したスクリプトは 新たに起動した Bash のプロセス(子プロセス)上で実行される。
$ bash スクリプトファイル
環境変数を追加するなどした際に ~/.bashrc
を再読み込みさせようとする場面で、この違いはうまくいかない原因になることがある。
$ bash ~/.bashrc
上記のコマンドは、呼び出し元のシェルプロセスには反映されない。
標準入出力 / リダイレクト / パイプ
$ exit
現在のシェルプロセスを終了する。スクリプト内で実行した場合、そのスクリプトの実行を即座に終了する。
$ exit
引数に数値を指定することで、終了ステータス を呼び出し元に返却することができる。
シェルからスクリプトを実行した場合には、スクリプトを起動したシェルに終了ステータスが返却され、シェルから別のシェルを起動し、そのシェル内で $ exit
を実行すると、元のシェルに制御が戻り、終了ステータスが返る。
$ exit 終了ステータス
$ exit
コマンドの終了ステータスには、直前のコマンドの $? をそのまま引数として渡すこともできる。
$ exit $?
$ tmux
Terminal Multiplexer
擬似端末 のセッションを管理するターミナルマルチプレクサ。
マルチプレクサ(MUX)は、複数の入力信号の中から1つを選択して出力するデジタル回路や装置のこと。
$ tmux
を利用することで、1つのターミナルアプリ内で複数の擬似端末を管理することができる。
ターミナルのタブ機能やペイン機能に似た操作ができるが、これらはターミナルアプリの GUI による視覚的な管理であるのに対し、$ tmux
は CUI による管理という違いがある。
通常、ターミナルのタブやペインに紐づくプロセスはターミナルを閉じると終了するが、$ tmux
のセッションは tmux
プロセスが動いている限り維持される。
また デタッチ、アタッチ という特徴的な機能がある。
さらに $ ssh
を利用したネットワーク越しの操作において、作業途中で接続が切断された場合でも、tmux
のセッションは端末の外部で動いているので、SSH 切断の影響を受けず、サーバー上で動作し続ける。そのため、SSH 再接続後に作業を再開させることができる。
$ tmux
コマンドの実行により、新規セッションが作成される。
$ tmux
$ tmux new -s セッション名
tmux
セッション内での操作は主にキー入力によって行うことができる。
Ctrl
+ B
を押した後に特定のキーを再び押すという順番になっていて、Ctrl
+ B
を プレフィックスキーと言う。
キー | 説明 |
---|---|
Ctrl + B → C
|
新しいウィンドウを作成(Create) |
Ctrl + B → N
|
次のウィンドウに切り替え(Next) |
Ctrl + B → P
|
前のウィンドウに切り替え(Previous) |
Ctrl + B → &
|
現在のウィンドウを削除 |
Ctrl + B → %
|
垂直にペインを分割 |
Ctrl + B → "
|
水平にペインを分割 |
Ctrl + B → 矢印キー
|
アクティブなペインを切り替え |
Ctrl + B → D
|
デタッチ |
$ tmux attach |
アタッチ |
$ tmux new |
新しいセッションを作成 |
$ tmux new -s セッション名 |
セッション名を指定して新しいセッションを作成 |
$ tmux list-sessions |
セッションを一覧表示 |
$ tmux kill-session |
セッションを終了 |
$ tmux kill-session -t セッション名 |
指定したセッションを終了 |
デタッチ / アタッチ
Detach / Attach
$ tmux
は 擬似端末 との接続を管理する役割を果たす。
(学習メモ:自分のようなLinux初学者には、デタッチやアタッチのイメージが非常に湧きづらかった。「計算装置(サーバ)に接続された 物理的な端末装置(キーボードとディスプレイ)」を頭に思い浮かべると、tmux
のデタッチ・アタッチの動作をイメージしやすいかもしれないと思った。昔は「端末を切り替える」と言ったら、作業者が物理端末Aから物理端末Bまで移動するしかなかった。)
デタッチ
- 現在のターミナルから
tmux
セッションの接続を切る - 作業者が端末の席から離れる、もしくは「ディスプレイの」電源を切るイメージ。計算装置は稼働し続ける。
-
tmux
セッション自体はサーバー上で動作し続ける - 現在のターミナルからは操作できなくなる
アタッチ
-
tmux
セッションを開く - 作業者が端末前の席に座る、もしくはディスプレイの電源を入れるイメージ。元々、計算装置は稼働している前提。
- ターミナルを通じて
tmux
セッションを操作できる状態になる
ウィンドウシステム
GUI を提供するための基盤となるソフトウェア。
以下の機能が提供される。
- ウィンドウの移動、サイズ変更などの管理
- 入力デバイス(マウス、キーボード)の管理
- グラフィック描画の管理
X Window System
Unix 系 OS で GUI を提供するシステム。
X や X11 と呼ばれることもある。
Linux では OS と一緒にインストールされることが多いが、技術的には OS に組み込まれている訳ではなく、独立したコンポーネントとして存在する。
クライアント - サーバ方式 で動作している。
-
X クライアント
- 描画を要求するプロセス
- 一般的な GUI アプリケーション
- Web ブラウザ、端末エミュレータなど
- 入力イベントをサーバから受け取り、アプリ内でイベントハンドリング処理を行う
-
X サーバ
/usr/bin/Xorg
- X クライアントからの描画要求を処理し、画面に描画する
-
デバイス管理 を担当する
- ディスプレイへの映像出力
- キーボード、マウスからの入力をイベントとしてクライアントに伝達する
私たちが普段使う PC は、サーバとクライアントが同じマシン上で動作しているが、別々のマシン上で動作させることもできる。
ネットワークで繋がった X サーバーに対してウィンドウを表示させることを特に X転送 という。X 転送は $ ssh -X
コマンドによって実現できる。
また、クライアントは $ xhost
を使用して利用できるサーバを許可、または拒否することができる。
$ xhost +ホスト名
$ xhost + # 全て許可
$ xhost -ホスト名
$ xhost - # 全て拒否
ホストとディスプレイの紐付けは 環境変数 $DISPLAY
で設定することができる。
ディスプレイ番号のデフォルト値は 0
。
$ DISPLAY=ホスト名:ディスプレイ番号
$ export DISPLAY
$ DISPLAY=ホスト名:ディスプレイ番号.スクリーン番号
$ export DISPLAY
クライアントとサーバは Xプロトコル で通信を行うので、異なる OS、ハードウェア、アーキテクチャ(CPU)同士でも動作させることができる。
X 自体にはウィンドウの装飾や配置の機能はなく、これらは ウィンドウマネージャ と呼ばれる独立したプログラムによって提供される。さらに、デスクトップ環境 は、ウィンドウマネージャに加えてパネルやファイルマネージャなどを統合したものである。
また近年では、X に代わって Wayland という新しいプロトコルが登場している。
Wayland
X Window System の後継となるウィンドウシステム。
X と同様にクライアント-サーバ方式を採用しているが、X のように中央管理の X サーバは存在せず、コンポジタ(Compositor) がクライアントと直接通信する形になっている。
コンポジタは、個々のクライアントから要求されたウィンドウを 合成(composite)してスクリーンイメージを生成する。
これにより、X よりもシンプルで効率的な描画が可能になる。
クライアントとサーバは Wayland プロトコル によって通信する。
ウィンドウの配置やタイトルバーの描画などの機能もコンポジタが直接管理するため、ウィンドウマネージャが存在しない点が X とことなr。
代表的な Wayland のコンポジタ
- Mutter(GNOME 用)
- KWin(KDE 用)
- Weston(Wayland のリファレンス実装)
- sway(i3 風のタイル型 Wayland コンポジタ)
ディスプレイマネージャ
X Window System 上で動作するソフトウェアコンポーネント。
ユーザーがログインするための GUI ログイン画面の提供、セッションの管理を担当する。
ディスプレイマネージャは、ユーザー名とパスワードを入力するログイン画面を表示し、ログイン後には適切なデスクトップ環境や X サーバ(/usr/bin/Xorg
)を起動する。
ディスプレイマネージャ | 特徴 |
---|---|
XDM |
X Display Manager 最も基本的なディスプレイマネージャ シンプルなログイン画面 |
GDM |
Gnome Display Manager GNOME デスクトップ環境に標準搭載 |
LightDM |
軽量で高速 Ubuntu のデスクトップ環境で利用される |
systemd
が採用された環境では、systemd
が display-manager.service
を起動する。
ウィンドウマネージャ
X Window System 上で X クライアントとして動作する コンポーネント、ソフトウェア。
ウィンドウの配置、サイズ変更、移動、装飾(ボーダーやタイトルバー)などの管理を担当する。
代表的なものには FVWM や IceWM、Openbox、Metacity などがある。
ウィンドウマネージャ | 特徴 |
---|---|
Metacity |
GNOME向けのウィンドウマネージャ。 シンプルで使いやすい。 |
KWin |
KDEで使用されるウィンドウマネージャ。 カスタマイズオプションが豊富。 |
i3 |
軽量で効率的なタイル型ウィンドウマネージャ。 キーボードでの操作性が重視されている。 |
Openbox |
軽量でカスタマイズ可能なウィンドウマネージャ。 デスクトップ環境に依存せず単独でも利用できる。 |