UNIXやLinuxのコマンド(基本)に関する世界観です。
「最新 Debian GNU/Linux 完全攻略ガイド(天野正樹)」を参考に執筆しました。
コマンドの基本は、「入力に対してデータの編集を行い、その結果を出力する」ということです。
これが、坂村健さんによる「痛快! コンピュータ学」でも言われているような、プログラムの基本です。
入力とはキーボード入力やファイルからの読み込みのことであり、出力とはモニター画面への表示やファイルへの出力のことです。
そして、UNIXではこれを「パイプ」や「リダイレクト」によって便利にします。パイプは、あるコマンドの出力を別のコマンドの入力として渡すことであり、リダイレクトは標準入出力とファイル読み書きを変換することです。
そのように、UNIXのコマンドは、入力と出力があって、入力に対して必要な処理を行った上で出力する、ということが基本になっています。コマンドを使う場合も、C言語などでコマンドを開発・実装する場合も、入力に対して出力するということが基本です。
原始的なインターフェースに見えるコマンドですが、なぜ、UNIX系のOSでは、このようなコマンドを今でも使うのでしょうか。
その鍵は、「リモート」と「自動化」にあります。
コマンドは、実際にそのマシン(ホスト)にログインして使う以外に、ネットワークで繋がったリモートホストにログインし、サーバーのように端末(制御画面)を持たないホストであっても、リモートから操作することができます。
このために使われるのは、telnetやrloginやsshといったリモートログインのための専用のコマンドです。
このようなリモートログインの環境では、通常のローカルのホストのコマンドと同じコマンドが使えます。ログインするのにパスワードや公開鍵暗号の鍵が必要になりますが、それさえ持っていれば離れたネットワークからでもログインできるのです。
もうひとつのコマンドの優位性は、スクリプトで自動化できることです。
コマンドは、シェルと呼ばれるソフトウェアの対話的なプロンプトで実行されますが、このプロンプトで対話的に実行するだけではなく、テキストファイルにコマンドの羅列を書いておいて、その書いておいたコマンド行を、いつでも、どれだけの行でも、何度でも自動的に実行することができます。
シェルにはbashやcshなどがあります。そして、パイプと組み合わせることで、スクリプトはさらに便利になります。なんらかの文字列をsedのようなフィルターコマンドで編集することで、bashに対するコマンド行に変換し、それをbashに送って実行する、などといった「シェル芸」が実現できるのです。
そのように、コマンドは非常に便利です。なので、GUIアプリケーションばかり使われるようになったWindowsパソコンの現代においても、エンジニアやサーバー管理者はUNIXをコマンドで操作します。
ほかにも、コマンドの優位性はあります。GUIでポチポチとマウスをクリックするよりも、効率的で間違いの少ない入力が可能です。いちいちスクロールバーをドラッグしてスクロールしながら、設定項目をひとつひとつ目で見て確認したり、現れるダイアログボックスの中のボタンをクリックしたりするよりも、多くの場合コマンド操作は効率的です。キーボードだけでコマンド行を書いてエンターで入力すればいいからです。設定についても、viでプレーンテキストの設定ファイルを編集するのは、難しく見えて本当はそのほうが間違いも少なく、ファイルそのものをコピーしてバックアップしたりできるといった利点もあります。
また、現代的なLinuxのようなOSでは、コマンドの入力支援のための機能が整っています。たとえば、bashのような多くのシェルでは、タブを押すことで入力中の残りの文字列を自動的に補完してくれるタブ補完、過去に実行したコマンドをヒストリーの記録から再び入力できるヒストリ機能、あらかじめ決められたコマンドをより少ないコマンドで実行できるエイリアスのような機能があります。
また、Linuxはさまざまなところでシェルスクリプトを使います。bashやX11の起動時に使われる初期化スクリプトや、デーモンの起動スクリプト、cronの定期的に実行されるスクリプトなどがシェルスクリプトによって記述されます。シェルスクリプトはC/C++のようなプログラミング言語と同じ機能を持っていて、変数や条件式や分岐・繰り返しや関数のある記述が可能です。
そのように、UNIXやLinuxでは、強力なコマンド機能を使うことができます。効率的で、素早く、コマンド行さえ間違っていなければ人為的な手作業による間違いのない、半自動的な操作ができるというだけでも、この恩恵は素晴らしいものです。あるいは、viやEmacsのようなテキストエディタからUNIXのシェルやコマンドを実行したり、Perlのようなプログラミング言語からUNIXコマンドを呼び出すこともできます。特にPerlなどでは正規表現を使った優れた文字列処理ができるため、かつてよりプログラマはUNIXとPerlを使いこなします。UNIXのさまざまな単純作業はPerl(あるいはawkなど)を使って自動化できるのです。PerlとUNIXはとても親和性が高く、PythonやRubyといった現代的な言語にもその目的と役割が受け継がれています。
さらにコマンドの優位性があるとしたら、それは四六時中モニターの前で待機している必要がないということです。コマンドは実行されている間、なんらかの対話的処理がもしなかった場合、モニターから離れてもコマンドの実行を続けてくれます。コマンドの実行が終わったら、またコマンドの入力ができますが、それをパイプやスクリプトを使って自動化できます。一部のソフトウェア(パッケージ管理システムなど)では、モニターに張り付いている必要がないように、-yのようなすべての対話的な入力にyesと自動的に答えてくれるオプションがあったりもします(expectのような対話的プロンプトの自動化専用のコマンドもある)。エラーの場合は中断してしまいますが、エラーがなければ最後にすべての仕事が終わるまで、別の作業(たとえば本を読む、コーヒーを飲む、インターネットをするなど)をすることができるのです。
ほかには、最近は構成管理ツールというソフトウェアがあって、サーバーの導入に必要な管理作業を自動化してくれたりします。そのようなツールを使うことで、たくさんの物理的なマシンがあった場合、それらに必要なミドルウェアを導入する作業をすべて自動化できます。なので、Windowsのように、いちいちひとつひとつのパソコンにOSのインストールや設定作業を行う必要は今ではもはやありません。パソコンがひとつやふたつであれば手動でインストールすることもありますが、サーバー環境では何十何百といったマシンを一度に管理したい場合もあります。そのような場合にはAnsibleのような構成管理ツールが便利です。
2023.09.10
まず、「ホスト名」とは、ネットワーク上のそのマシン(ホスト)に付けられた名前のこと。
ワークステーションに接続するためには、telnetなどにホスト名あるいはIPアドレスを指定する。
telnetでホスト「hogepc」に接続する時は、
telnet hogepc
とする。Windowsでtelnetを行うには、TeraTermなどを用いる。
(「情報基礎概論 第4版 喜久川政吉・殿塚勲 共著(学術図書出版社)」を参考に執筆しました。)
後日注記:現在のLinuxでは、telnetはパスワード情報などを暗号化せず平文でネットワーク送信してしまうため、利用を推奨されません。SSHを使うようにしましょう。
SSHも参照のこと。
UNIXのコマンド操作を行うには、まず、カレントディレクトリの概念を知っておく必要がある。
カレントディレクトリとは、「ユーザーが今作業を行っているディレクトリ」のこと。
今いる場所を変えるには、cdコマンドを使う。
たとえば、/usr/ディレクトリに移動するには、
cd /usr/
とする。~はホームディレクトリ、/はルートディレクトリ、.あるいは./は現在のディレクトリ、..あるいは../はひとつ上のディレクトリを表す。単にhogeとした場合は、現在のディレクトリの中のhogeディレクトリあるいはhogeファイルを表す。
現在のディレクトリの中のhogeファイルを読みたいなら、
cat hoge
とすれば、hogeファイルの中身をターミナルに全出力する。しかしながら、上の方が流れてしまうため、通常はパイプを使ってlessに渡す。lessはページャと呼ばれるコマンドプログラムで、テキストを上下にスクロールして閲覧することができる。
cat hoge | less
UNIXでは、このように「catコマンドの出力を別のlessコマンドに渡す」といったことが|を使って簡単にできる。これをパイプという。
また、lessに渡すのではなく、いったんファイルに出力して、そのファイルを表示したい時などに、リダイレクトと呼ばれる機能が使える。
cat hoge > hoge1.txt
>とすればファイルへと出力でき、逆に<とすればファイルから全行を入力に使うことができる。この時、C言語のプログラムでは、標準入出力と呼ばれる機構を使って入出力管理が行われているため、どんなソフトウェアでも、標準入力や標準出力としてリダイレクトやパイプによるストリームを渡すことができる。
コマンドにはオプションがあり、標準で実行されるプログラムに「このようにしてほしい」というオプション命令を加えて実行することができる。
たとえば、lsで詳細表示と全てのファイルを表示する場合は、
ls -al
とする。オプションの詳細については、manコマンドを実行することでオンラインマニュアルを読むことができる。たとえば、
man ls
と実行すれば、lsコマンドのオンラインマニュアルを閲覧できる。
コマンド | 説明 |
---|---|
login | ログインしている時に、 他のユーザで再ログインするために使う。 |
man | オンラインマニュアル。 man lsとすればlsについての使い方やオプションの情報が見れる。 |
echo | 引数となる文字列を出力する。 特に確認のために環境変数を出力したり、 一行をファイルに出力したい場合などに使う。 |
alias | コマンドの別名。 rmなどの危険なコマンドに、 常に-i(確認が必要)オプションをつける場合などに使う。 |
UNIXシステムの管理者ユーザー。システムを変え、破壊する権限を持つ。rootになるためには、su -を実行する。
基本的に、ホームディレクトリ以外はrootの管理に置かれるため、ホームディレクトリ以外のファイルを変更したい時は、su -を実行して、rootパスワードを入力する。
Ubuntuなどでは、普段使う際にはrootユーザーが存在せず、suの代わりにsudoを使う。
また、rootが所有者となっているシステムのファイルにアクセスできるかどうかは、パーミッションによる。パーミッションはファイルの読み込み、書き込み、実行に関する権限を与えるもので、所有ユーザ、所有グループ、その他のユーザに対して許可と不許可を設定できる。
ユーザーに与えられた、自由なディレクトリ。
通常は/home/username/の中にあり、自分の好きなように使うことができ、他のユーザーからは秘匿にすることができる。
コマンドを入力し、実行するための、端末とシェルにおいて、$や%は一般ユーザーでの操作、#はrootユーザーでの操作を表す。この文字を入力する必要はない。
たとえば、
$ ls hoge
と記述されていれば、一般ユーザーのシェルで、
ls hoge
と入力してエンターキーを押せばいい。
あるいは、
# apt install gcc
と記述されていれば、まずrootユーザーになるためにsuコマンドを使用する。
su -
このように入力して(-を忘れないように注意)、rootユーザーのパスワードを聞かれたら入力する。パスワードは画面には表示されないが、間違いなく入力してエンターキーを押してログイン後のシェルを起動すると、シェルのプロンプトが$や%から#に変化する。
この状態で、
apt install gcc
と入力してエンターキーを押せばいい。
もし、root権限が必要なくなったら、
exit
と実行すれば、その時点で起動中のシェルは終了し、一般ユーザーのシェルに戻る。rootユーザーはどんなシステムの破壊行為も可能であるため、できるだけ一般ユーザーで作業することが強く推奨される。
Ubuntuなどでは、sudoコマンドをsuコマンドの代わりに使用することができる。この時、rootユーザーのパスワードは聞かれず、今ログインしている一般ユーザーのパスワードが要求される。
sudo apt install gcc
sudoを使うことができるユーザーは、/etc/sudoersでユーザーが登録されていることが条件となる。
シェルとコマンド操作の基本は以下のようなページがとても参考になる。
シェルとは、ライン入力からコマンドのプログラムを実行するソフトウェア。Linuxでは、標準的にbashが使われる。
PATHは環境変数。シェルにコマンド名を入力して実行した時、PATHに含まれているディレクトリからプログラムが検索される。以下のコマンドでPATHを表示できる。
echo $PATH
bashは、初期化設定ファイルを読み込みます。
ファイル名 | 説明 |
---|---|
~/.bashrc | ユーザーの設定で、シェルの起動時に毎回読み込まれる。 |
~/.bash_profile | ユーザーの設定で、ログイン時のシェル(ログインシェル)で一回だけ読み込まれる。 |
/etc/profile | システムの標準設定で、ログインシェルで読み込まれる。 |
/etc/bashrc | システムの標準設定で、シェルの起動時に毎回読み込まれる。 |
~/はホームディレクトリのことです。
UNIXシステム管理(システム情報と設定)を参照のこと。
途中まで打ち込んで、タブキーを押すと、コマンド補完が出来ます。
Bashを参照のこと。
コマンドを組み合わせて使うことが出来るパイプとリダイレクトについて。パイプはコマンドの出力を別のコマンドの入力に渡す。たとえば、
cat hoge.txt | grep A | grep B | grep C
とすれば、hoge.txtの中のAとBとCが含まれた行を表示できる。
リダイレクトは、ファイルの内容を標準入力や標準出力と変換することのできる機能。プログラミングの視点から言えば、C言語の標準入出力のAPIでファイルを操作できる。
Bashのさまざまな機能を参照のこと。
bashでのシェルスクリプトについて。基本的にコマンドの羅列をスクリプトに書くことで、そのコマンドを実行できます。またプログラミングも可能。
Bash(シェルスクリプト)を参照のこと。
シェルでコマンドを実行する際、ファイル名などに*や?などのワイルドカードが使える。
*は任意の文字列(複数文字)、?は任意の文字(1文字)を表す。
たとえば、
ls /etc/*.conf
などとできる。
coreutilsのgitで基本的なコマンドのコードを読むことが出来ます。
たとえばcat.cはこんな感じです。
コマンド一覧。Linuxのコマンドの中で一番基本的なものは、coreutilsと言うパッケージに含まれていますが、さらに高度で便利なコマンドが沢山あります。
コマンドの別名(エイリアス)を設定する。
alias rm='rm -i'
何も引数を与えずにaliasコマンドを実行すると、定義されたエイリアスの一覧が見れる。
マニュアルページを表示する。
man man
主なオプションは-C(設定ファイルの指定)、-P(ページャの指定)、-k(キーワード検索)。
Linuxコマンド(ドキュメント)を参照のこと。
ファイルの中身を表示する。lessではスクロールでファイルの全体を観覧出来る。
find / | less
lessのコマンドは、fあるいはスペースで一画面下にスクロール、bで一画面上にスクロール、jで一行下、kで一行上、qで終了、/で検索、?で逆方向に検索、nで次の検索場所に移動、Nで前の検索場所に移動。
lessと同様にファイルの内容を表示するページャだが、EUC-JP、UTF-8、Shift-JISなどの文字コードに対応している。
ディレクトリの中身のリスト(ファイル一覧)を表示する。
ディレクトリの中のファイル一覧と、ファイルの情報を表示する。ディレクトリの中のファイル内容をリストする時に使う。オプションを使いこなそう。
ls -Al
主なオプションは-a(ドットファイルや隠しファイルを含むすべてのファイルを表示)、-l(詳細表示、更新日時などが表示される)、-t(更新時間で並び替え)、-x(拡張子で並び替え)、-F(ディレクトリや実行ファイルのタイプ識別子をマーキングして表示)、-R(子ディレクトリのディレクトリ階層を再帰的に辿って表示)、-i(ファイルのi-node番号を表示)。
現在のディレクトリを変更(移動)する。
cd ..
主なオプションは-L(シンボリックリンクの場合にリンク先のディレクトリに移動する)、-P(シンボリックリンクの場合にリンク先のディレクトリに移動しない)。
カレントディレクトリ(作業ディレクトリ)のパスを表示する。
pwd
ディレクトリを新しく作成する。
mkdir -m 755 hoge
主なオプションは-p(上位のディレクトリ階層すべてを作成する)。
ファイルやディレクトリをコピーする。
cp -r hoge1 hoge2
主なオプションは-i(同じ名前のファイルがあった場合に確認)、-r(ディレクトリごと再帰的にコピー)、-p(更新日時を保つ)。
ファイルやディレクトリを移動・名前変更する。
mv hoge1 hoge2
主なオプションは-i(同じ名前のファイルがあった場合に確認)。
ファイルやディレクトリを削除する。
間違えて使わないように、エイリアスなどで確認表示をデフォルトにすることもある。
rm hoge
主なオプションは-i(削除を確認する)、-f(警告を表示しない)、-r(ディレクトリ以下のすべてのファイルを再帰的に削除)。
ディレクトリを削除する。空のディレクトリを削除する。
ファイルの中身を表示する。ファイルの全体をコマンドラインに出力する。
cat hoge_a.txt hoge_b.txt > hoge_c.txt
よく使うオプションは-n(行番号を表示)。
ファイルのリンク(ハードリンク・シンボリックリンク)を作る。
ファイルやディレクトリにリンクを設定。シンボリックリンクを作る時に使う。
ln -s /usr/local/bin bin
-sをつけるとシンボリックリンクを、つけないとハードリンクを作成する。
タイムスタンプを更新する。内容を変更せずftpなどで再更新したい時などに使う。
ファイルを復元不可能にする。
主なオプションは-v(処理の状況を表示)、-z(shred処理の痕跡を残さないために、最後にnullデータで上書きする)。
Linuxコマンド(ユーザープログラム)を参照のこと。
ファイルのパーミッション・オーナーを変更する。
UNIXシステム管理(ユーザーとパーミッション)を参照のこと。
実行中のプロセス一覧を表示する。
$ ps PID TTY TIME CMD 400 pts/2 00:00:00 bash 410 pts/2 00:00:00 ps
(初心者のためのシェル(bash)入門 - 2ch-Linux-Beginnersより編集して引用。)
主なオプションはa(全てのプロセスを表示)、r(実行中のプロセスを表示)、-u ユーザ名(ユーザ名やユーザIDで抽出)。
また、Tオプションをつけて表示される状態は、Sが割り込み可能なスリープ、Dが割り込み不可能なスリープ、Rが実行中・実行可能、Tがトレース中・停止中、Zがゾンビ。
Linuxコマンド(プロセス)を参照のこと。
プロセスを強制終了する。Ctrl+Cも使います。
$ cp /home/hoge/bigfile1 /home/hoge/bigfile2 & $ ps PID TTY TIME CMD 400 pts/2 00:00:00 bash 412 pts/2 00:00:00 cp 414 pts/2 00:00:00 ps $ kill 412
(初心者のためのシェル(bash)入門 - 2ch-Linux-Beginnersより編集して引用。)
killのオプションは-s シグナル名(送信するシグナルを指定する)、-l(シグナルの一覧を表示する)。
Linuxコマンド(プロセス)を参照のこと。
ファイルを検索して一覧表示する。
find /
findを参照のこと。
特定の文字列を含む行を抽出する。
find . | grep hoge
grepを参照のこと。
アーカイブファイルを作成・展開する。
tar czvf hoge.tar.gz hoge_dir/ tar xzvf hoge.tar.gz
xは展開、cは作成、tは表示、rは追加。
Linux アーカイブ・同期・デバイス処理を参照のこと。
dateは日付を表示・設定する。単にdateと入力して実行すると現在の日付と時刻を表示する。
後日注記:dateは、シェルスクリプトなどでよく使われる。たとえば、
$(date +%Y.%m.%d)
のように、現在の日時をシェルスクリプトの中で指定したい場合に使える。+以降の文字列はフォーマットを表し、%Yは年、%mは月、%dは日に自動で変換される。
UNIXシステム管理(cron)も参照のこと。
calはカレンダーの表示を行う。cal -yで一年分、cal -3で三か月分(今月に加えて先月と来月)を表示する。
ユーザを新しく追加する。
主なオプションは--conf ファイル名(設定ファイルを指定する)、--shell シェル名(ログインシェルを指定する)。
UNIXシステム管理(ユーザーとパーミッション)を参照のこと。
ユーザのパスワードを変更する。
passwdは、特定のアカウントを停止するために使うこともできる。この場合のオプションは、-lは停止、-uは停止の解除、-Sは状態の表示となる。
UNIXシステム管理(ユーザーとパーミッション)を参照のこと。
システムを停止させるコマンド。
haltのオプションは-w(再起動・停止をせずにwtmpに記録のみを行う)、-d(wtmpに記録しない)、-f(強制的に再起動・停止をする)。
shutdownのオプションは-h(シャットダウン)、-r(再起動)、-F(再起動する際にfsckを行う)、hh : mm(指定した時間にシャットダウンを行う)、+数字(指定した分後にシャットダウンを行う)、now(コマンド入力をしてすぐにシステムを終了する)。
コマンド | 説明 |
---|---|
set | シェル変数の設定と表示。 |
setenv | 環境変数の設定。(csh/tsch) |
export | 環境変数の設定。(sh/bash) |
env/printenv | 環境変数の一覧の表示・設定。 |
もっと沢山のコマンドがありますが、coreutilsのgitで基本的なコマンドのコードを読むことが出来ます。
以下の書籍・ページが参考になります(上のコマンド一覧は以下の情報を基に記述しました)。