未経験からのフルスタックエンジニア

スキルをつけよう!未経験からフリーランスエンジニアへの成長記録

Linux学習履歴(6)~シェルの賢い使い方~

以下の記事の続きです

atora1992.hatenablog.com

Linuxコマンドライン入門』が日ごとに6日間分別れているので、今回は6日目の中間地点までの内容についてです。

コマンドの備忘録的になってしまうと思いますので、悪しからず。

6日目

シェルを賢く使う

ワイルドカード応用

ワイルドカードは以下の記事で取り上げたように、「*」や「?」といった特殊文字を用いて、ファイルやディレクトリを柔軟に指定できる方法でした。

atora1992.hatenablog.com

特殊文字は、コマンドではなくシェルによって展開されます!

上記の2つに追加して新たに2つの表記法を紹介します。

  • [【文字の並び】]
  • {【文字列1】,【文字列2】,..}
[【文字の並び】]でいずれかの文字を表す

例えば、"[A-Z]"はAからZまでの文字(アルファベット大文字)の全てを表します。 ですので、以下のコマンドでは、先頭がアルファベット大文字のディレクトリ一覧を表示できます。

$ ls -ld [A-Z]*

逆に、先頭がアルファベット大文字以外を指定したければ、以下のように"^"を用います。

$ ls -ld [^A-Z]*
{【文字列1】,【文字列2】,..}で文字列を展開する

{}内に、複数の文字列をカンマで区切って記述すると、シェルはその順に文字列を展開します(ブレース展開)。

$ echo {gif,jpg}
gif jpg

※カンマの前後にスペースは入れれません

これを使えば、拡張子を指定してファイル一覧の表示などが簡単にできます。

$ ls *.{gif,jpg}

シングルクォーテーションとダブルクォーテーション

今まで、特殊文字の働きを打ち消して(クォーティング)文字として認識させるときには、シングルクォーテーションまたはダブルクォーテーションでくくってきたかと思います。

クォーテーションの中にクォーテーションを含むには、外側を違うクォーテーションでくくれば大丈夫です。

それでは、この両者は同じなのでしょうか?実は、両者には特殊文字を打ち消す力の強さに違いがあります。

強さはシングルクォーテーションの方が強いです。
シングルクォーテーション>ダブルクォーテーション

シングルクォーテーションは全ての特殊文字を打ち消します。
一方で、ダブルクォーテーションは「$」と「`」の働きは打ち消しません

ですので、以下のような違いが生まれます

$ echo "Today is `date`"  #ダブルクォーテーションでくくるので、「`」の働きは残存
→Today is 2019820日,,,

$ echo 'Today is `date`'  #シングルクォーテーションだと「`」の働きが消される
→Today is `date`

(バッククォーテーションのによるコマンド置換は以下の記事を参考にしてください)

atora1992.hatenablog.com

シングルの方が強力と覚えれば大丈夫です。

コマンド履歴の活用

コマンド履歴の一覧を表示する

$ history
$ history 【任意の数字】  #数字で指定した直近の履歴を表示

数字はヒストリ番号です。

コマンド履歴内の任意のコマンドを実行するには、ヒストリ番号を指定して実行可能です。

$ !【ヒストリ番号】


$ !!  #直前に実行されたコマンドを実行する

履歴を見るだけでなく、インクリメンタルサーチを行うことも可能です。
Ctrl + Rキー
でサーチもモードになります。

文字を入力するたびに、コマンドが検索され、目的のコマンドが見つかったらEnterを押すことで実行できます。

文字を入力して、同じ文字列で検索したい場合には、もう一度Ctrl + Rキーを押すことで可能です。

また、見つかったコマンドを編集したい場合には、Escキーを押すことで可能です。

シェル変数

シェルで使用する変数のことです。以下のコマンドで、変数に値を格納できます。

$ 【変数名】=【値】

e.g.
$ text=Hello  #textという変数にHelloを代入
$ echo $text  #$で変数から値を取り出す
→Hello

※イコールの前後にスペースは入れれません

特殊文字を値をして格納したい場合には、クォーテーションで括ります。
ただし、ある文字列ないで変数から値を取り出したい場合には、外側はダブルクォーテーションでなければなりません。というのも、シングルクォーテーションでくくると、$による値の取り出しの働きが消されてしまうからです。

変数の定義を削除する。

$ unset 【変数名】

シェル変数がどこまでなのかは、シェル側で勝手に判断してくれます。
例えば、「/」や「.」のような記号があると、その前までが変数だと判断します。

なので、変数の後に英数文字が続く場合には、変数名を{【変数名】}とくくる必要があります。

$ Main=~/Documents/Main

$ cd $Main
→~/Documents/Mainに移動
$ cp $Main/2019.txt ~
→~/Documents/Mainにある2019.textをホームディレクトリコピー

$ echo ${Main}OK
→~/Documents/MainOK

フォアグラウンド・ジョブとバックグラウンド・ジョブ

シェルはターミナル(・エミュレーター)内で実行されているコマンドをジョブとして管理します。

ジョブは以下の2つに大別されます。

  1. フォアグラウンド・ジョブ
  2. バックグラウンド・ジョブ
フォアグラウンド・ジョブ

ターミナル前面で実行されているジョブです。つまり、実行が完了するまではコマンドプロンプトは戻りません(入力できない)。

バックグラウンド・ジョブ

ターミナル背面で実行されているジョブです。つまり、同時に複数のコマンドを実行することが可能になります。

バックグラウンド・ジョブとしてコマンドを実行するには、コマンド名の後に「&」を記述します。

$ 【コマンド名】&

一度、フォアグラウンド・ジョブとして実行した後でも、バックグラウンド・ジョブにすることも可能です。

$ 【コマンド名】  #フォアグラウンド・ジョブとして実行
↓  Ctrl + Zキーでジョブを一時停止
$  #コマンドプロンプトが戻る
↓
$ bg  #バックグラウンド・ジョブに変更する

実行しているジョブの一覧を表示するにはjobsコマンドを実行します。

MacBook-Pro:~ ATORA$ xclock&
[1] 3338
MacBook-Pro:~ ATORA$ xclock&
[2] 3340
MacBook-Pro:~ ATORA$ xclock&
[3] 3341
MacBook-Pro:~ ATORA$ xclock&
[4] 3342
MacBook-Pro:~ ATORA$ jobs
[1]   Running                 xclock &
[2]   Running                 xclock &
[3]-  Running                 xclock &
[4]+  Running                 xclock &

上記の例では、xclockを4つバックグラウンド・ジョブとして実行しました。
一覧の左の数字はジョブ番号です。(各コマンド後に表示される数値はプロセスIDといいます(後述))
「+」が表示されているのがカレントジョブで、後述するfgコマンドの対象となります。
「-」が表示されているのが一つ前のカレントジョブです。

バックグラウンド・ジョブをフォアグラウンド・ジョブにするにはfgコマンドを用います。

$ fg %【ジョブ番号】

※引数なしの場合は、カレントジョブが対象となります。

バックグラウンド・ジョブを終了させるにはkillコマンドを用います。

$ kill %【ジョブ番号】
$ kill -s SIGKILL %【ジョブ番号】  #暴走状態になった(終了できない)ジョブを停止させる

ジョブというのは、実行中のシェルから見た処理の単位です。なので、ターミナルを複数立ち上げていると、どれぞれのターミナルごとにジョブ番号は1から振られていきます。

一方で、システムから見た実行中のプログラムのことはプロセスと呼びます。プロセスにはシステムで重複のないプロセスIDが振られます。

現在実行中のプロセス一覧はpsコマンドで表示できます。

$ ps

$ ps -e  #システムないの全てのプロセス一覧を表示

上記のコマンドで表示されるPIDがプロセスIDです。TTYにはジョブを実行中のターミナルの名前が表示されます。

指定したプロセスに対してシグナルを送ることも可能です。

$ kill -s 【シグナル】 【プロセスID】

シグナル例
SIGTERM:ジョブ停止命令(シグナル指定なしの場合はデフォルトでSIGTERM)
SIGKILL:SIGTERMで停止しない場合に停止させる
SIGTSTP:プログラムの一時停止(Ctrl + Zキーではこのシグナルが送られている)
SIGINT:プログラムの停止

次の記事へ

atora1992.hatenablog.com