Bash のコマンドと演算子

完了

どのようなシェル言語にも、最もよく使われるコマンドがあります。 Bash のレパートリーを増やす第一歩として、最もよく使われるコマンドを調べてみましょう。

Bash のコマンド

一般的な Bash コマンドとその使用方法を見てみましょう。

ls コマンド

ls では、現在のディレクトリまたはコマンドへの引数で指定したディレクトリの内容の一覧が表示されます。 それ自体では、現在のディレクトリにあるファイルとフォルダーが一覧表示されます。

ls

名前がピリオドで始まるファイルとディレクトリは、既定では非表示になります。 これらのアイテムをディレクトリの一覧に含めるには、-a フラグを使用します。

ls -a

現在のディレクトリにあるファイルとディレクトリに関するさらに詳しい情報を取得するには、-l フラグを使用します。

ls -l

いくつかの JPEG と PNG および gifs という名前のサブディレクトリが含まれるディレクトリの出力の例を次に示します。

-rw-rw-r-- 1 azureuser azureuser  473774 Jun 13 15:38 0001.png
-rw-rw-r-- 1 azureuser azureuser 1557965 Jun 13 14:43 0002.jpg
-rw-rw-r-- 1 azureuser azureuser  473774 Mar 26 09:21 0003.png
-rw-rw-r-- 1 azureuser azureuser 4193680 Jun 13 09:40 0004.jpg
-rw-rw-r-- 1 azureuser azureuser  423325 Jun 10 12:53 0005.jpg
-rw-rw-r-- 1 azureuser azureuser 2278001 Jun 12 04:21 0006.jpg
-rw-rw-r-- 1 azureuser azureuser 1220517 Jun 13 14:44 0007.jpg
drwxrwxr-x 2 azureuser azureuser    4096 Jun 13 20:16 gifs

各行には、対応するファイルまたはディレクトリに関する詳細な情報が表示されています。 その情報には、割り当てられているアクセス許可、所有者、バイト単位のサイズ、最後に変更された日時、ファイル名またはディレクトリ名が含まれます。

cat コマンド

ファイルの内容を確認したいものとします。 そのためには、cat コマンドを使用できます。 ファイルがテキスト ファイルでない限り、出力はあまり意味がありません。 次のコマンドでは、/etc ディレクトリに格納されている os-release ファイルの内容が表示されます。

cat /etc/os-release

これは、実行している Linux ディストリビューションがわかる便利なコマンドです。

NAME="Ubuntu"
VERSION="18.04.2 LTS (Bionic Beaver)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 18.04.2 LTS"
VERSION_ID="18.04"
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
VERSION_CODENAME=bionic
UBUNTU_CODENAME=bionic

/etc は、Linux では特別なディレクトリです。 そこには、システム構成ファイルが含まれています。 何をしているのかわかっている場合を除き、このディレクトリからファイルを削除しないでください。

sudo コマンド

一部の Bash コマンドは、ルート ユーザー (システム管理者またはスーパーユーザー) だけが実行できます。 これらのコマンドのいずれかを十分な権限なしで実行しようとすると、失敗します。 たとえば、cat を使用して /etc/at.deny の内容を表示できるのは、スーパーユーザーとしてログインしているユーザーのみです。

cat /etc/at.deny

at.deny は、他の Bash コマンドを使用して後で実行するためにジョブを送信できるユーザーを決定する特別なファイルです。

ほとんどの場合は、ルートとして実行する必要はありません。危険すぎます。 スーパーユーザーとしてログインせずに管理特権を必要とするコマンドを実行するには、コマンドの先頭に sudo を付けます。

sudo cat /etc/at.deny

sudo は、"superuser do" (スーパーユーザーで実行) を意味します。それを使用すると、この 1 つのコマンドについては、ルート ユーザー レベルのアクセス許可で実行することが、シェルに伝えられます。

cdmkdirrmdir コマンド

cd は、"change directory" (ディレクトリの変更) を意味し、名前のとおりのことが行われます。つまり、現在のディレクトリが別のディレクトリに変更されます。 Windows の類似機能と同じように、あるディレクトリから別のディレクトリに移動することができます。 次のコマンドでは、現在のディレクトリの orders という名前のサブディレクトリに変更されます。

cd orders

ディレクトリ名として .. を指定することで、1 つ上のディレクトリに移動できます。

cd ..

次のコマンドを実行すると、ホーム ディレクトリ (最初にログインしたときに表示されるディレクトリ) に移動します。

cd ~

ディレクトリを作成するには、mkdir コマンドを使用します。 次のコマンドでは、現在の作業ディレクトリに orders という名前のサブディレクトリが作成されます。

mkdir orders

サブディレクトリとその下の別のサブディレクトリを 1 つのコマンドで作成する場合は、--parents フラグを使用します。

mkdir --parents orders/2019

rmdir コマンドは、ディレクトリが空の場合にのみ、これを削除 (除去) します。 空ではない場合は、代わりに警告が表示されます。 幸い、rm コマンドを -r (再帰) フラグと組み合わせて使用し、空ではないディレクトリを削除できます。 その場合、このコマンドは rm -r のようになります。

rm コマンド

rmrm コマンドは、"remove" (削除)の略です、rm ではファイルが削除されます。 したがって、次のコマンドを実行すると、0001.jpg がなくなります。

rm 0001.jpg

次のコマンドでは、現在のディレクトリにあるすべてのファイルが削除されます。

rm *

rm には注意してください。 これは危険なコマンドです。

-i フラグを指定して rm を実行すると、削除する前に考えることができます。

rm -i *

すべての rm コマンドで -i を指定することを習慣にしておけば、Linux 最大のミスの犠牲者にならなくて済むかもしれません。 恐ろしいことは rm -rf / コマンドで、ドライブ全体のすべてのファイルが削除されます。 ルートのすべてのサブディレクトリとそのサブディレクトリが再帰的に削除されます。 -f ("force": 強制的) フラグを使用すると、プロンプトが表示されないので、事態はいっそう悪化します。 絶対に行わないでください。

空ではない orders という名前のサブディレクトリを削除する場合は、次のように rm コマンドを使用できます。

rm -r orders

これにより、orders サブディレクトリと、他のサブディレクトリも含めてその中にあるすべてのものが削除されます。

cp コマンド

cp コマンドでは、ファイルだけでなく、必要に応じてディレクトリ全体 (およびサブディレクトリ) がコピーされます。 0001.jpg のコピーを 0002.jpg という名前で作成するには、次のコマンドを使用します。

cp 0001.jpg 0002.jpg

0002.jpg が既に存在する場合は、Bash によって自動的に置き換えられます。 それが意図したことである場合は便利ですが、古いバージョンを上書きすることがわかっていなかった場合は、ありがたいことではありません。

幸いにも、-i ("interactive": 対話形式) フラグを使用すると、既存のファイルを削除する前に警告が表示されます。 この方がはるかに安全です。

cp -i 0001.jpg 0002.jpg

もちろん、ワイルドカードを使用して、複数のファイルを一度にコピーできます。 現在のディレクトリにあるすべてのファイルを photos という名前のサブディレクトリにコピーするには、次のようにします。

cp * photos

photos という名前のサブディレクトリ内のすべてのファイルを、images という名前のサブディレクトリにコピーするには、次のようにします。

cp photos/* images

この場合、images ディレクトリは既に存在するものとします。 そうでない場合は、次のコマンドを使用すれば、それを作成し、"かつ"、photos ディレクトリの内容をコピーすることができます。

cp -r photos images

-r は "recursive" (再帰的) を意味します。-r フラグの追加の利点は、photos にそれ自体のサブディレクトリが含まれる場合は、それも images ディレクトリにコピーされることです。

ps コマンド

ps コマンドを実行すると、現在実行中のすべてのプロセスのスナップショットが取得されます。 引数を指定せずに単独で使用すると、すべてのシェル プロセスが表示されます。つまり、大した数ではありません。 しかし、-e フラグを指定すると話が違います。

ps -e

-e では、実行中の "すべての" プロセスの一覧が表示され、通常はかなりの数になります。

システムで実行されているプロセスについてさらに総合的に見たい場合は、-ef フラグを使用します。

ps -ef 

このフラグでは、実行中のすべてのプロセスの名前、プロセス ID 番号 (PID)、親の PID (PPID)、開始された時刻 (STIME) が表示されます。 また、接続されている端末 (TTY、ある場合)、消費した CPU 時間 (TIME)、および完全なパス名も示されます。 次に要約した例を示します。

UID         PID   PPID  C STIME TTY          TIME CMD
root          1      0  0 13:35 ?        00:00:03 /sbin/init
root          2      0  0 13:35 ?        00:00:00 [kthreadd]
root          3      2  0 13:35 ?        00:00:00 [rcu_gp]
root          4      2  0 13:35 ?        00:00:00 [rcu_par_gp]
root          5      2  0 13:35 ?        00:00:00 [kworker/0:0-cgr]
root          6      2  0 13:35 ?        00:00:00 [kworker/0:0H-kb]
root          8      2  0 13:35 ?        00:00:00 [mm_percpu_wq]
root          9      2  0 13:35 ?        00:00:01 [ksoftirqd/0]
root         10      2  0 13:35 ?        00:00:02 [rcu_sched]

ちなみに、ps の次のような使用方法が示されているドキュメントを見たことがあるかもしれません。

ps aux

ps auxps -ef は同じです。 このような二重性の原因は、POSIX Unix システム (Linux はその 1 つ) と BSD Unix システム (最も一般的なものは macOS) の履歴的な違いにまで遡ります。 当初、POSIX では -ef が使用されており、BSD では aux が必要でした。 現在は、どちらのオペレーティング システム ファミリでも、双方の形式が受け入れられます。

これは、すべての Linux コマンドについて、マニュアルをよく見る必要がある理由を思い出させてくれるよい例です。 Bash の学習は、2 つ目の言語として英語を学ぶのに似ています。 ルールには多くの例外があります。

w コマンド

ユーザーは訪れて、去っていきます。ときには、まったく望ましくないユーザーが来ることもあります。 従業員が他の機会を得ようと会社を辞めたとき、システム管理者は、その従業員が会社のコンピューター システムにログインできなくなるようにするよう求められます。 また、システム管理者は、誰がログインしているか、そして誰がログインすべきではないかを、把握している必要もあります。

サーバーにログインしているユーザーを確認するには、Linux の w ("who": 誰) コマンドを使用します。 このコマンドでは、現在コンピューター システム上にいるユーザーと、そのユーザーのアクティビティに関する情報が表示されます。 w では、ユーザー名、IP アドレス、ログインした日時、現在実行しているプロセス、およびそれらのプロセスの消費時間が示されます。 これは、システム管理者にとって重要なツールです。

Bash の I/O 演算子

Bash コマンドとその多くのオプションを実行するだけで、多くのことを Linux で行うことができます。 しかし、I/O 演算子を使ってコマンドを組み合わせてこそ、本当に作業をやり遂げることができます。

  • < では、キーボード以外のソースに入力がリダイレクトされます
  • > では、画面以外の出力先に出力がリダイレクトされます
  • >> では、同じことが行われますが、上書きではなく、追加されます
  • | では、あるコマンドの出力が別のコマンドの入力にパイプされます

現在のディレクトリにあるすべてのものの一覧を取得し、出力を listing.txt という名前のファイルにキャプチャすることにします。 次のコマンドでそれが行われます。

ls > listing.txt

listing.txt が既に存在する場合は、上書きされます。 代わりに >> 演算子を使用すると、ls からの出力は、listing.txt に既に含まれる内容の後に追加されます。

ls >> listing.txt

パイプ演算子は非常に強力です (頻繁に使用されます)。 この演算子では、1 番目のコマンドの出力が 2 番目のコマンドの入力にリダイレクトされます。 たとえば、cat を使用して大きなファイルの内容を表示しても、スクロールが速すぎて読めないものとします。 結果を more などの別のコマンドにパイプすることで、出力を管理しやすくなります。 次のコマンドでは、現在実行中のすべてのプロセスが一覧表示されます。 ただし、画面がいっぱいになると、ユーザーが Enter キーを押して次の行を表示するまで、出力は一時停止します。

ps -ef | more

出力を head にパイプし、最初の数行だけを表示することもできます。

ps -ef | head

または、出力をフィルター処理して、"daemon" という単語が含まれる行のみを表示したいものとします。その 1 つの方法は、ps から Linux の便利な grep ツールに出力をパイプすることです。

ps -ef | grep daemon

出力は次のようになります。

azureus+  52463  50702  0 23:28 pts/0    00:00:00 grep --color=auto deamon
azureuser@bash-vm:~$ ps -ef | grep daemon
root        449      1  0 13:35 ?        00:00:17 /usr/lib/linux-tools/4.18.0-1018-azure/hv_kvp_daemon -n
root        988      1  0 13:35 ?        00:00:00 /usr/lib/accountsservice/accounts-daemon
message+   1002      1  0 13:35 ?        00:00:00 /usr/bin/dbus-daemon --system --address=systemd: --nofork --nopidfile --systemd-activation --syslog-only
daemon     1035      1  0 13:35 ?        00:00:00 /usr/sbin/atd -f
root       1037      1  0 13:35 ?        00:00:00 /usr/bin/python3 -u /usr/sbin/waagent -daemon
root       1039      1  0 13:35 ?        00:00:00 /usr/lib/linux-tools/4.18.0-1018-azure/hv_vss_daemon -n
azureus+  52477  50702  0 23:28 pts/0    00:00:00 grep --color=auto daemon

ファイルを入力として使うこともできます。 既定では、標準入力はキーボードから取得されますが、リダイレクトすることもできます。 キーボードではなくファイルから入力を取得するには、< 演算子を使用します。 システム管理者がよく行う作業の 1 つは、ファイルの内容の並べ替えです。 名前が示すように、sort ではテキストがアルファベット順に並べ替えられます。

sort < file.txt

並べ替えられた結果を新しいファイルに保存するには、入力と出力を "同時に" リダイレクトできます。

sort < file.txt > sorted_file.txt

I/O 演算子を使用すると、必要に応じて Linux コマンドをチェーンできます。 次のようなコマンドについて考えてみます。

cat file.txt | fmt | pr | lpr

cat からの出力は fmt に送られ、fmt からの出力は pr 送られます。以下同様です。 fmt では、結果が整った段落に書式設定されます。 pr では結果がペジネーション処理されます。 そして、lpr ペジネーション処理された出力がプリンターに送られます。 すべてが 1 行で済みます。