Linuxでは、ユーザが入力したコマンドの解釈/実行や実行中のプログラムの制御は、ユーザとシステムの仲介役である「シェル」というプログラムが担当します。Linuxのシェルは、単なるユーザインターフェースとして存在するだけではなく、プログラミング言語としての機能もあります。
ユーザがターミナルで打ち込んだコマンドは、「シェル」というプログラムが解釈して、システムの中心部分であるカーネルに伝えます。
シェルはカーネルとユーザとの橋渡しをする
「シェル」はLinuxにおける名称で、一般的には「コマンドインタプリタ」などと呼ばれる種類のプログラムです。現在ではさまざまな種類のシェルが存在します。
現在ではLinuxで動作する多くのシェルがあり、使い勝手や機能はさまざまです。
シェルはBourneシェルを起源とするBシェル系と、cshを起源とするCシェル系に分類されることがあります。以下に、主なシェルについてまとめておきましょう。
システムにログインした直後に起動されるシェルをログインシェルと呼びます。ユーザーごとのログインシェルは /etc/passwd ファイルに書かれています。
シェルが起動すると、コマンドプロンプトを表示し入力待ちになります。コマンドプロンプトの表示は、bashのデフォルトで一般ユーザーの場合
[ユーザー名@ホスト名 カレントディレクトリ名]$
スーパーユーザ(root)の場合、
[root@ホスト名 カレントディレクトリ名]#
になっています。
[root@localhost ~]# |
コマンドプロンプトの表示を変更するにはシェル変数のPS1~PS4を変更することで可能です。
変数は、プログラムを実行する際に、シェルからプログラムへ情報を渡すひとつの方法となります。プログラムは特定の変数を"環境の中で"探します。変数が見つかれば格納されている値を使用します。変数は、システム、他のシェル、あるいは別のプログラムによってセットされます。
標準的な Linux の変数は、環境変数とシェル変数のふたつのカテゴリに分類されます。大まかな説明として、シェル変数は一時的な作業の為に現在のシェルで使用されるものです。環境変数はより重要な意味を持ち、ログイン時にセットされてログイン中は常に有効となります。慣例的に、環境変数の名前には大文字が用いられ、シェル変数には小文字が用いられます。
シェル変数は現在実行中のシェルだけで有効な変数ですが、環境変数はシェルから実行したコマンドにも引き継がれる変数です。シェル変数および環境変数にはあらかじめ役割が決められているものと、ユーザーが自分で役割を決めるものがあります。
bashでは、シェル変数と環境変数はほとんど一体化して扱われており、シェル変数をエクスポート(外部に公開)すると環境変数になります。
一方、tcshでは、シェル変数と環境変数を別の変数として扱い、変数に値を設定するコマンドも異なります。
環境変数にはあらかじめ役割が決められているものがあります。もちろん、ユーザーが設定内容を変更することもできます。
●環境変数USER | 現在ログインしているログイン名 |
HOME |
現在ログインしているユーザーのホームディレクトリのパス |
HOSTNAME | 使用中のコンピュータの名前 |
LANG | ロケール(言語指定) |
PATH | 実行可能なコマンドのあるディレクトリの指定。「:」で区切りながら複数のディレクトリを指定できる |
SHELL | 実行するシェル |
TERM | 利用されるターミナル |
PWD | 現在いるパス(カレント・ディレクトリ) |
LOGNAME | ログインシェルのユーザー名 |
● PATH
コマンドの検索パス名を設定します。複数のパス名を設定したい場合には「:」(コロン)で区切ります。左から順に検索されます。
$ echo $PATH /usr/lib/qt-3.3/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin |
検索パス名として合計8つのディレクトリが指定されていることが分かります。最初の7個のパス名はシステムのディレクトリ、最後のパス名はユーザーの実行可能ファイルを格納するディレクトリです。
ユーザーのホームディレクトリにあるbinディレクトリをPATHに追加するには
$ PATH=$PATH:$HOME/bin |
● PWD
カレント・ディレクトリが設定されます。
● USER
ユーザー名が設定されます。
● HOME
ユーザーのホーム・ディレクトリが設定されます。
● HOSTNAME
ホスト名が設定されます。
どのような環境変数が設定されているかを調べるには、printenv コマンドを使用します。printenvを引数なしで実行すると、設定されているすべての環境変数が表示されます。
$ printenv |
環境変数とは、シェルから起動されたすべてのプロセスに有効な変数のことです。環境変数は、いったんシェル変数に値を代入して、export コマンドによって設定します。例えば、環境変数PAGERにlessを設定するには以下のようにします。
$ PAGER=less |
$ export PAGER |
また、以下のように1つのコマンドで設定することもできます。
$ export PAGER=less |
環境変数はプログラムから起動された子プロセスでも有効ですが、シェル変数は子プロセスでは無効(未定義)になります。
env コマンドは、環境変数を設定してプログラムを実行するコマンドです。
● env コマンド構文
env [オプション] [変数名=値] [コマンド [引数]...] |
|
-i | 環境が空の状態でコマンドを実行する |
-0 | 環境変数の一覧出力時に改行を入れない |
-u 変数名 | 指定した環境変数を一時的に削除して実行する |
環境変数のLANGにC(英語)を設定して、dateコマンドを実行
$ env LANG=C date Tue Jan 9 18:45:14 JST 2018 |
$ date 2018年 1月 9日 火曜日 18:45:34 JST |
変数を定義するには、
書式: 変数=値
で定義します。変数名には、英字、数字、アンダーパー(_)を使うことができますが、先頭の文字に数字を使うことはできません。また、大文字小文字は区別されます。
「=」の前後には、スペースを入れてはいけません。
値の途中にスペースが入る場合は、「"」または「'」で両端を囲みます。
変数に入っている値を参照する場合は、変数名の前に「$」マークを付けて使います。
変数の値を確認するには、echo コマンドを使います。
$ hensuu=atai $ echo $hensuu <---変数名の前に$マークを付けて使います。 atai |
変数を削除するには、unset コマンドを使います。
$ unset hensuu $ echo $hensuu <---値は表示されません。 |
コマンドライン上の文字の編集には、テキストエディタで利用するカーソル移動や編集のキーバインドがそのまま利用できます。Linux では標準的に Emacs のキーバインドが適用されています。
●コマンドラインで利用できる編集のキーバインド例Ctrl + d | カーソル上の一文字を消去 |
Ctrl + k |
カーソルより右側を消去 |
Ctrl + b | カーソルを左に移動 |
Ctrl + f | カーソルを右に移動 |
Esc + b | カーソルを1単語左に移動 |
Esc + f | カーソルを1単語右に移動 |
Ctrl + a | カーソルを行頭に移動 |
Ctrl + e | カーソルを行末に移動 |
※ Ctrl + d はCtrlキーとdキーを同時に押すことを表しています。
Linux のシェルでは、単なる文字ではなく、特別な意味を持っている記号または文字があります。これらの文字のことをメタキャラクタと呼ばれます。
& ; ` ' \ " | * ? ~ < > ^ ( ) [ ] { } $ \n \r
上の文字がメタキャラクタです。
これらを普通の文字として扱うためには、以下のように3通りのエスケープ方法があります。
& | コマンドの後に「&」を付けて実行すると、そのコマンドはバックグラウンドで実行される。 |
; | コマンドとコマンドの区切り |
` (バッククォーテーション) | バッククォーテーションの中にコマンドが存在すると、コマンドを実行した結果が展開されて使われます。また、変数が存在するとその変数にコマンドが入っていた場合もそのコマンドを実行した結果が使われます。 |
' (シングルクォーテーション) |
シングルクォーテーションで囲まれた文字列はそのまま文字として扱われます。 |
\ | \ マークに続けてメタキャラクタが記述されているとそのメタキャラクタではなく、その文字そのものとして使われます。 |
" (ダブルクォーテーション) |
ダブるクォーテーションで囲まれた文字列もそのまま文字として扱われますが、変数がその中に存在する場合は、変数の値を文字列として扱います。 |
| | パイプ |
* | 0文字以上の文字または文字列にマッチします。 |
? |
任意の1文字にマッチします。「a?」はaa,ab,a1にマッチし a,abcは対象外になります。 |
~ | ホームディレクトリ |
< |
入力 |
> | 出力 |
^ |
キャレットは行の先頭位置を表す |
( ) | カッコ内の文字列をグルーピングします。順序を変更する場合に使います。 |
[ ] | [ ]内に列挙されている文字のいずれか一文字にマッチします。 「a[bcd]」は、ab,ac,adが対象になります。連続した文字列には「-」が使用可能です。「0-9」=「0123456789」 「!」を使うとマッチしない範囲を指定します。「!a-z」は 小文字以外の任意の文字にマッチします。 |
{ } | { }内の文字を使って文字列を生成します。「test{1,2}」は、test1,test2を生成します。 |
$ | ドルマークは行の末尾位置を表す |
\n | 改行を表す |
\r | リターンを表す。 |
シェルは入力・実行されたコマンドの履歴を記録する機能を持っており、過去に実行したコマンドとその実行時刻を後で確認することができます。標準は$HOME/.bash_historyに保存されます。保存ファイルを変更する場合は、環境変数HISTFILEを変更します。
履歴を残す数は、環境変数HISTSIZEとHISTFILESIZEで設定できます。デフォルトは1000です。
(全ユーザーの環境変数HISTSIZEおよびHISTFILESIZEの値を変更する場合は、/etc/profile内にある該当部分を変更します)
↑,Ctrl+p | 1つ前のコマンドを表示する |
↓,Ctrl+n |
1つ次のコマンドを表示する |
!文字列 | 履歴の中から指定した文字列で始まるコマンドを実行する |
!?文字列 | 履歴の中から指定した文字列が含まれるコマンドを実行する |
!! | 直前に実行したコマンドを実行する |
!履歴番号 | 履歴番号のコマンドを実行する。 |
過去に入力したコマンドのヒストリ・リスト(履歴一覧)は、history コマンドを入力すると出力されます。古いものから順に番号が付いています。ただし、引数指定をしないとすべてのヒストリ・リストが出力されます。引数で数字(n)を指定すると、n回前までのコマンドが出力されます。
$ history 5 |
1010 history 1011 ls -al 1012 history 5 1013 cat file1.txt 1014 history 5 |
左端の数字はコマンドの入力順の番号で、ヒストリ・リストを参照する際の索引として利用できます。例えば、1011番目に表示されたコマンド「ls -l」を再度実行したい場合には、
$ !1011 |
合計 920 dr-xr-x---. 33 root root 4096 4月 6 02:33 2013 . dr-xr-xr-x. 24 root root 4096 4月 8 12:42 2013 .. -rw-------. 1 root root 9006 4月 6 01:55 2013 .ICEauthority drwxr-xr-x. 2 root root 4096 9月 19 08:07 2012 .abrt drwx------ 3 root root 4096 4月 2 17:41 2013 .anthy -rw-------. 1 root root 20019 4月 8 01:53 2013 .bash_history -rw-r--r--. 1 root root 18 5月 20 19:45 2009 .bash_logout ・ ・ 省略 |
ヒストリ・リストを対話的に出力することもできます。カーソル移動キーの「↑」か「 Ctrl + p 」で一つ前のコマンドが出力され、「↓」か「 Ctrl + n 」で一つ先のコマンドが出力されます。
この設定を無効にしたい場合には、.bashrcに次の行を追加しておきます。
unset HISTFILESIZE unset HISTFILE |
Linuxには、ファイルやディレクトリの名前を先頭の数文字入れてTabキーを押すことで、残りの文字を保管してくれる機能があります。
複数の候補が見つかった場合には、特定できる部分(すなわち一致しなくなる直前の文字)までを出力し警告音が鳴ります、再度Tabキーを押すことで、該当するファイルやディレクトリの名前の一覧を表示します。続きの文字を入力して、再度Tabキーを押すことで一致する名前を表示します。
$ cat dd [tab] [tab] |
dd.log ddrescue-1.16/ ddrescue.log ddlescue.log ddrescue-1.16.tar.gz ddrescuecmd |
シェルのコマンドプロンプトでコマンドを入力して実行するとシェルはその処理を実行します。
コマンドには、シェル自身が持っているコマンドとコンピュータ上にファイルとして存在するコマンドとがあります。
前者を内部コマンド、後者を外部コマンドと言います。
外部コマンドの場合は、その場所を表すディレクトリを指定せずにコマンドを実行すると、シェルは環境変数のPATHに記述されているディレクトリを順に探し、その外部コマンドのファイルが見つかればそれを実行します。
外部コマンドがカレントディレクトリにあることがわかっていれば、コマンドの前に「./」を付けて実行します。
$ ./command |
シェルの一番基本的な機能として、コマンドインタプリタの機能があります。これには、次の動作が含まれます。
このようなコマンドの逐次解釈を行うプログラムをコマンドインタプリタ (command interpreter) と言います。
2.コマンドの連続実行コマンドとコマンドの間を ; で区切って書くと、前のコマンドが終了したらすぐに次のコマンドを実行します。
ただしパイプとは違い、前のコマンドの結果を次のコマンドに渡すわけではありません。
$ ls -al ; cat file1.txt ; ps -aux |
通常、コマンドは1行につき1つのみ記述できますが、コマンドを1行に複数個記述したい場合は「;」(セミコロン)を使用します。 また、コマンドラインから複数のコマンドを連続実行したい場合にも、「;」(セミコロン)で区切って複数のコマンドを記述することでコマンドを連続実行することができます。この場合は、先のコマンドがエラーなどで正常終了しなくても、次のコマンドは実行されます。
● 連続コマンドの実行制御コマンド1 ; コマンド2 | コマンド1に続けてコマンド2を実行する |
コマンド1 && コマンド2 |
コマンド1が正常終了したときのみコマンド2を実行する |
コマンド1 || コマンド2 | コマンド1が正常終了しなかったときのみコマンド2を実行する |
(コマンド1 ; コマンド2) | ひとかたまりのコマンドグループとして実行する。これら二つのコマンドを「サブシェル」のもとで実行する(グループ化)。 サブシェルで行った環境変更はもとのシェルに影響しない。 よって、状態を一時的に変更して作業するときに便利 |
{コマンド1 ; コマンド2} | 現在のシェル内でコマンドを実行する |
複数のコマンドの実行結果をまとめて、次のコマンドに引き渡す。
$ (date ; cd /tmp ; ls -a) > kiroku.log |
グループ化のメリットは、cd /tmp等でカレントディレクトリを移動してもコマンド実行後には影響しない。
[~]$ (cd /tmp; ls -a) |
. .esd-501 pulse-OjUXHjGSCetn .. 01.txt pulse-Zz22eOQVH6JE .ICE-unix Samba設定.pdf pulse-j22B4iqraEdW .X0-lock firefox-20.0.1.tar.bz2 virtual-kawamoto.3vcFZm .X11-unix gnome-system-monitor.root.335782085 virtual-root.oS1G3e .esd-0 orbit-gdm | [~]$ |
exec に指定したコマンドを実行すると、新しいプロセスを作成せずに、現在のジョブと置き換えて実行されます。
また、何もコマンドを指定せずにリダイレクトを利用すると、現在のシェルのリダイレクトを切り替えられます。
exec [オプション] [コマンド] |
|
-c | 空の環境で実行される。 |
-a parm | 0番目の引数にparmを渡す |
シェルから普通にコマンドを実行すると、シェルは以下のことを行います。
一方、シェルから「 exec コマンド 」と exec 付きでコマンドを実行すると、シェルは fork() しないで、いきなり コマンドを exec() します (シェルの内部コマンド exec(1) を実行すると、内部でシステムコール exec(2) が呼ばれるということです)。シェルのプロセス情報は コマンド のプロセスの情報で上書きされます。なお、子プロセスは生成されないので、シェルと コマンド のプロセス ID は同じになります。
「パス」とは、特定のファイルやディレクトリの位置を示す文字列のことです。
外部コマンドは、ファイルとして存在するのでその存在場所をシェルが知っていないと実行できません。
環境変数のPATHは、そのコマンドを探すべきディレクトリの一覧です。PATHのディレクトリを順に調べてそのコマンドを探します。
PATH以外の場所にあるコマンドは実行できないのでしょうか。実は、実行可能です。コマンドを入力するときに、そのコマンドの場所(ディレクトリ)と一緒に指定すれば実行することができます。
そのディレクトリの指定をパスと言います。パスの指定方法に絶対パスと相対パスがあります。
ルートディレクトリを基点として目的のファイル、ディレクトリまでの道筋のことを絶対パスと言う。
常に「 / 」から始まり、ディレクトリ階層を「/」で区切りながら指定します。
基点となる現在位置(カレントディレクトリ)から、目的のファイル、 ディレクトリまでの道筋のことを相対パスと言う。
あるディレクトリの一階層上のディレクトリを親ディレクトリと呼び「 .. 」で表します。現在のディレクトリをカレントディレクトリと呼び「 . 」で表します。
シェルを使ううえで必要な知識の一つに引用符の理解があります。Linuxには3種類の引用符があり、それぞれシングルクォーテーション、ダブルクォーテーション、バッククォーテーションと呼ばれています。各引用符には変数の扱いやコマンドの実行といった点でそれぞれ特徴があります。
まずそれぞれの引用符について簡単に説明します。
$ echo 'pwd' pwd $ echo "pwd" pwd $ echo `pwd` /home/sakura |
バッククォーテーションで囲った場合だけカレントディレクトリが出力されることが確認できます。このようにバッククォーテーションを使用した場合は文字列をコマンドとして実行することになります。
変数を使用した場合は、
$ PWD=pwd <--- 変数 PWD に文字 pwd を入れる $ echo '$PWD' $PWD $ echo "$PWD" pwd $ echo `$PWD` /home/sakura |
引用符の中に引用符を書いた場合
$ PWD=pwd $ echo '"$PWD"' <--- (1) "$PWD" $ echo '`$PWD`' <--- (1) ‵$PWD‵ $ echo "'$PWD'" <--- (2) 'pwd' $ echo "`$PWD`" <--- (3) /home/sakura $ echo `"$PWD"` <--- (4) -bash: $PWD: コマンドが見つかりません $ echo `"$PWD"` <--- (5) /home/sakura |
(1) シングルクォーテーションに囲まれた文字列はたとえ中に別のクォーテーションがあったとしてもそのままの文字列として出力されます。
(2) ダブルクォーテーションで囲まれた文字列の中にシングルクォーテーションがあった場合は、シングルクォーテーションはそのまま文字として、変数は展開して出力されます。
(3) ダブルクォーテーションで囲まれた文字列の中にバッククォーテーションがある場合は、バッククォーテーションの展開が行われます。
(4) バッククォーテーションで囲まれた文字列の中にシングルクォーテーションがある場合、変数がそのままの形(ここでは$PWD)でコマンドを実行しようとするためエラーとなります。
(5) バッククォーテーションで囲まれた文字列の中にダブルクォーテーションがある場合は、初めにダブルクォーテーションの中の変数が展開されるため、`pwd`として処理されることになります。
コマンド・関数・ファイルなどに関するオンラインマニュアルページを参照するには、man コマンドを使用します。
マニュアルのファイルは、/usr/share/manにおかれます。manコマンドの検索ディレクトリは、環境変数MANPATHが参照されます。MANPATHに指定がなければ、/etc/man.config(または/etc/man.conf)ファイルに指定されたデフォルトが使用されます。
manコマンドが使用するページャは環境変数PAGERに指定されたものが使われます。(通常はless)。別のページャを使う場合はPAGERに指定します。
man [セクション番号] 名称 |
|
manコマンドは最初に見つかったマニュアルを表示して終了します。
セクション番号(章番号)を指定すると、manはそのセクションからのみマニュアルを検索します。
セクション番号(章番号)の分類は以下の通りです。
同じ名称のマニュアルが異なるセクションに存在する場合は、セクション番号を指定してください。
-a | 条件に合致するすべてのページを表示します。 |
-f | マニュアルの見出しを表示します。 |
-h | ヘルプメッセージを表示します。 |
-w | ファイルの場所を表示します。 |
-k キーワード | 指定されたキーワードを含むコマンドを検索して、概要を表示します。 |
-p ペイジャー | 使用するペイジャーを指定します。デフォルトは「less」です。 |
1 | ユーザコマンド |
2 |
システムコール |
3 | サブルーチン |
4 | デバイス |
5 | ファイルの書式 |
6 | ゲーム |
7 | その他 |
8 | システム管理ツール |
9 | Linuxカーネル独自のルーチン |
n | 分類前の新しいドキュメント |
o | 猶予期間として保持されている古いドキュメント |
l | 独自のローカルなドキュメント |
:e [file] | 新規にファイルを読み出す。ファイル名を指定しない場合は、現在のファイルを再度読み出す |
:n |
次のファイルを閲覧する |
:p | 前のファイルを閲覧する |
:x | 先頭のファイルを閲覧する |
/pattern | 現在位置からファイルの末尾方向へpatternを検索し、移動する |
?pattern | 現在位置からファイルの先頭方向へpatternを検索し、移動する |
b, ESC + v | 前の画面へ戻る。コマンドを入力する前に数字を入力すると、指定した画面数ずつ戻る |
d | 半画面進む。コマンドを入力する前に数字を入力すると、指定した半画面数ずつ進む |
e, j | 1行進める。コマンドを入力する前に数字を入力すると、指定した行数ずつ進む |
f, SPACE | 次の画面へ進む。コマンドを入力する前に数字を入力すると、指定した画面数ずつ進む |
g, < | ファイルの先頭へ移動する |
G, > | ファイルの末尾に移動する |
h, H | lessの操作ヘルプを表示する |
n | 検索を再度行う |
N | 前回の検索を逆方向に行う |
r | 画面を再度書き換える |
u | 半画面戻る。コマンドを入力する前に数字を入力すると、指定した半画面数ずつ戻る |
q, Q | 終了する |
y, k | 1行戻る。コマンドを入力する前に数字を入力すると、指定した行数ずつ戻る |
見出し | 説明 |
NAME(名前) |
コマンドやファイルの名前と簡単な説明 |
SYNOPSIS(書式) | 書式(オプションや引数) |
DESCRIPTION(説明) | 詳細な説明 |
OPTIONS(オプション) | 指定できるオプションの説明 |
FILES(ファイル) | 設定ファイルなど関連するファイル |
ENVIRONMENT(環境変数) | 関連する環境変数 |
NOTES(注意) | その他の注意事項 |
BUGS(バグ) | 既知の不具合 |
SEE ALSO(関連項目) | 関連項目 |
AUTHOR(著者) | プログラムやドキュメントの著者 |
$ man 1 less |
$ man -k less |
$ LANG=C man pwd |
www.it-shikaku.jp