Linuxの基礎コマンド群「Coreutils」を使いこなそう
- 1 はじめに
- 2 coreutilsパッケージが提供するコマンド
- 3 コマンドのマニュアルを読むには
- 4 各コマンドに共通のオプション
- 4.1 「--help」オプション
- 4.2 「--version」オプション
- 5 ファイルを出力するコマンド
- 5.1 ファイルを結合して表示する「cat」
- 5.2 ファイルの先頭部分だけを表示する「head」
- 5.3 ファイルに行番号を付加する「nl」
- 5.4 ファイルを逆順に表示する「tac」
- 5.5 ファイルの末尾部分だけを表示する「tail」
- 6 ファイルを分割をするコマンド
- 6.1 ファイルを特定の条件で分割する「csplit」
- 6.2 ファイルを分割する「split」
- 7 ファイルの中身をチェックするコマンド
- 7.1 MD5チェックサムを計算する「md5sum」
- 7.2 SHA-1チェックサムを計算する「sha1sum」
- 7.3 SHA-256チェックサムを計算する「sha256sum」
- 7.4 ファイルの行数、文字数、バイト数を出力する「wc」
- 8 ファイルを編集/変換/ソートするコマンド
- 8.1 BASE64エンコード/デコードを行う「base64」
- 8.2 ファイルの中身をシャッフルする「shuf」
- 8.3 ファイルの中身をソートする「sort」
- 8.4 文字の置換と削除を行う「tr」
- 8.5 ファイルから重複を削除する「uniq」
- 9 ファイルやディレクトリに関するコマンド
- 9.1 ファイルやディレクトリをコピーする「cp」
- 9.2 ファイルのコピーと変換を行う「dd」
- 9.3 属性を指定してコピーする「install」
- 9.4 リンクを作成する「ln」
- 9.5 ディレクトリの内容を表示する「ls」
- 9.6 ディレクトリを作成する「mkdir」
- 9.7 ファイルを移動する「mv」
- 9.8 ファイルを削除する「rm」
- 9.9 ディレクトリを削除する「rmdir」
- 9.10 カレントディレクトリを表示する「pwd」
- 9.11 ファイルやディスクを安全に消去する「shred」
- 10 ファイルの属性を変更するコマンド
- 10.1 ファイルの所有グループを変更する「chgrp」
- 10.2 ファイルのパーミッションを変更する「chmod」
- 10.3 ファイルの所有者を変更する「chown」
- 10.4 ファイルのタイムスタンプを変更する「touch」
- 11 ユーザーとシステムに関するコマンド
- 11.1 システムのアーキテクチャを表示する「arch」
- 11.2 時刻を表示する「date」
- 11.3 所属しているグループ名を表示する「groups」
- 11.4 ユーザーIDやグループIDを表示する「id」
- 11.5 システム情報を表示する「uname」
- 11.6 システムの稼動時間を表示する「uptime」
- 11.7 ログイン中のユーザー情報を表示する「who」
- 11.8 自分のユーザー名を表示する「whoami」
- 12 プロセスに関するコマンド
- 12.1 プロセスにシグナルを送る「kill」
- 12.2 処理を一時停止する「sleep」
- 12.3 タイムアウトを指定してコマンドを実行する「timeout」
- 13 おわりに
はじめに
厳密な意味での「Linux」とは、OSのカーネルのみを指す名称です。カーネルは文字通り、OSのコアとなる非常に重要なプログラムですが、ユーザーがカーネルを直接操作するわけではありません。カーネルだけではOSとしては成立せず、ユーザーが操作するための様々なアプリケーションやコマンドが別途必要となります。そのため、一般的なLinuxディストリビューションには最初から便利なコマンドが数多く用意されています。ファイルをコピーする「cp」コマンドや、ファイルの中身を表示する「cat」コマンドなどを使ったことがある方も多いでしょう。
cpやcatのような基礎コマンドは「GNU Coreutils」により提供されています。GNU CoreutilsはUnixライクなOSに当然存在することが期待される、基本的なコマンドやユーティリティの詰め合わせです。
Coreutilsには、誰もが知っている定番から「こんな便利なものがあったのか」と驚くようなものまで、多種多様なコマンドが存在します。LinuxのCLIに習熟するには、何はともあれCoreutilsを知るべきというのが筆者の考えです。もちろんWSLにおいても、この事情は変わりません。そこで今回は、Linuxの基礎と言えるCoreutilsに含まれるコマンドについて解説します。
coreutilsパッケージが提供するコマンド
Coreutilsは、Ubuntuにおいて「coreutils」パッケージによって提供されています。第3回で紹介したdpkgコマンドを使って、coreutilsパッケージの中身を調べてみましょう。
dpkgコマンドは-Lオプションとパッケージ名を指定すると、そのパッケージ内に含まれているファイルの一覧が表示できます。パッケージ内にはマニュアルやドキュメントなども含まれているため、grepコマンドにパイプして「/usr/bin」という文字列でフィルタします。パッケージからインストールされる実行バイナリは「/usr/bin」ディレクトリ以下にインストールされるため、これでコマンドのみを絞り込めるのです。すると実に100を越えるコマンドが提供されていることが分かります*1。
*1: このように数をカウントしたいときは、後述するwcコマンドを活用すると便利です。$ dpkg -L coreutils | grep '/usr/bin'
本記事では、こうした100以上のコマンドのうち、よく使うものや、知っておくと便利そうだと筆者が考えたものに絞って紹介します。
コマンドのマニュアルを読むには
Coreutilsの各コマンドにはマニュアルが用意されています。マニュアルを読むには「man」コマンドの引数に、調べたいマニュアル(コマンド)名を指定してください。例えば、catコマンドのマニュアルを読むには以下のように実行します。
$ man cat
なお、コンテナなどの軽量な環境では、manコマンド自体がインストールされていないこともあります。そのような場合はmanパッケージをインストールしてください。
$ sudo apt install -U -y man
前述の通り、Coreutilsに含まれるコマンドは非常に多く、またそれぞれのコマンドの使い方も複雑なため、本記事では概要の紹介に留めます。ぜひ手元のWSL環境でdpkgコマンドを使ってどのようなコマンドが存在するのかを調べたら、manコマンドでマニュアルを一読してみてください。
各コマンドに共通のオプション
一般的に、CLIのコマンドはそれぞれ独自のオプションを持っていますが、Coreutilsの各コマンドで共通しているオプションもあります。以下の2つのオプションは覚えておくと良いでしょう。
「--help」オプション
文字通り、そのコマンドの簡易的なヘルプを呼び出すオプションです。manで読めるマニュアルよりも簡単な解説を標準出力に表示できます。主要なオプションをちょっと調べたいような場合は、manを呼び出すより簡単で便利です。例えば、catコマンドのヘルプは以下のようにして呼び出せます。manと内容と比べてみましょう。
$ cat --help
「--version」オプション
そのコマンド(Coreutils)のバージョンを表示するオプションです。トラブルに遭遇した際など、使っているコマンドのバージョンが重要な情報となります。「何か挙動がおかしいな」と思ったら、まずは使っているバージョンを確認してみましょう。
ファイルを出力するコマンド
ファイルを結合して表示する「cat」
catは、Coreutilsの中でもトップクラスによく使われるコマンドの1つでしょう。主にテキストファイルの中身を出力する目的で使用されています。以下は、example.txtというファイルの中身を表示する例です。
$ cat example.txt
実は、catは「concatenate」の略で「連結する」という意味を持っています。このコマンドの主目的は複数のファイルを連結することです。引数に複数のファイルを指定すると、それらを繋げて表示します。以下のコマンドを実行するとexample1.txt、example2.txt、example3.txtの3つのファイルを繋げて表示できます。
$ cat example1.txt example2.txt example3.txt
リダイレクトすれば、連結したファイルを保存することもできます。また、テキストファイルだけでなく、バイナリファイルを連結することもできます。
$ cat example1.txt example2.txt example3.txt > concatinate.txt
ファイルの先頭部分だけを表示する「head」
headコマンドは、指定したファイルの先頭部分のみを表示します。デフォルトでは先頭から10行を表示します。以下はexample.txtの先頭10行のみを表示する例です。
$ head example.txt
「-n」オプションに続いて数値を指定することで、指定した行数のみを表示することもできます。また「-c」オプションに続いて数値を指定すると、指定したバイト数のみを表示できます。複数あるファイルの概要を確認したいような場合、catですべてを表示するのは冗長でしょう。そのようなときによく利用します。
ファイルに行番号を付加する「nl」
nlコマンドは、catと同じくファイルの中身を表示しますが、出力の際に行番号を付加します。以下はexample.txtに行番号を付加して出力する例です。
$ nl example.txt
実は、catコマンドにも行番号を付加する「-b」オプションが存在します。そのため、上記のnlコマンドの実行例は、以下のcatコマンドの実行例と同じになります。
$ cat -b example.txt
なお、nlコマンドはデフォルトで空行には行番号を付加しません。以下のように「-ba」オプションを付けると空行にも行番号を付加します。また、この挙動はcatコマンドの「-n」オプションと同等です。
$ nl -ba example.txt $ cat -n example.txt
ファイルを逆順に表示する「tac」
tacコマンドもcatコマンドと同じく、ファイルの中身を出力します。ただし行単位で逆順に表示します。つまりファイルの末尾の行が1行目、末尾の直前の行目が2行目、となります。コマンド名はその挙動に由来し、catをひっくり返したものです。
$ tac example.txt
ファイルの末尾部分だけを表示する「tail」
headコマンドと対になるのがtailコマンドです。このコマンドはファイルの末尾の10行のみを表示します。「-n」オプションや「-c」オプションも、末尾からカウントする点以外はheadコマンドと同じです。以下はexample.txtの末尾10行を表示する例です。
$ tail example.txt
tailコマンドがよく使われるのは、追記され続けるファイルの監視です。例えば、サーバーのログファイルには動作中のアプリの情報が書き込まれ続けています。tailコマンドに「-f」オプションを付けると、こうしたファイルをリアルタイムに監視し続けることができます。以下はerror.logというログファイルを監視する例です。
$ tail -f error.log
また、ログファイルは定期的にローテーションされるのが一般的です。監視中にローテーションされるファイルを追従するには、--retryオプションを併用してください。
ファイルを分割をするコマンド
ファイルを特定の条件で分割する「csplit」
csplitコマンドは、行番号や正規表現を使ってファイルを分割するコマンドです。例えば、以下はexample.mdというMarkdownファイルをレベル2の見出し(##2つで始まる行)で分割します。また、パターンの後には分割を何回繰り返すかを指定します。ここでは「{*}」を指定し、ファイル末尾まで繰り返す指定をしています。
$ csplit example.md '/^## .*/' '{*}'
分割した結果は、カレントディレクトリに「xx00」「xx01」「xx02」……という連番のファイルとして保存されます。そのため、以下のようにcatコマンドで連結することで元のファイルを復元できます。なお、この「xx」にあたるプレフィックスは、オプションで変更することも可能です。
$ cat xx*
ファイルを分割する「split」
splitコマンドは、csplitコマンドと同様にファイルを分割できます。ただし、csplitコマンドが正規表現で柔軟に条件を指定できたのに対し、splitは一定のサイズや行数ごとに分割します。分割単位はデフォルトで1,000行です。また「-l」オプションで行数を指定できます。以下はexample.txtを10行ごとに分割する例です。
$ split -l 10 example.txt
分割した結果はcsplitとは多少異なり「xaa」「xab」「xac」……という名前のファイルとして保存されますが、catコマンドで連結できる点は同様です。
ファイルの中身をチェックするコマンド
MD5チェックサムを計算する「md5sum」
MD5チェックサムの計算と照合を行うのがmd5sumコマンドです。以下のコマンドを実行すると、example.txtファイルのチェックサムを計算できます。
$ md5sum example.txt
「-c」オプションを指定すると、ファイルから計算したチェックサムを読み込み、ファイルとの照合が行えます。以下のコマンドではMD5SUMSというファイルから対象のファイル名とそのチェックサムを読み込み、実際のファイルと比較して破損や改竄がないかを確認します。
$ md5sum -c MD5SUMS
SHA-1チェックサムを計算する「sha1sum」
SHA-1チェックサムの計算と照合を行うのがsha1sumコマンドです。オプションも含め、使い方はmd5sumと同様です。
SHA-256チェックサムを計算する「sha256sum」
SHA-256チェックサムの計算と照合を行うのがsha1sumコマンドです。オプションも含め、使い方はmd5sumと同様です。UbuntuのISOイメージファイルのチェックサムはSHA-256で提供されているので、ここではそのチェック方法を紹介しましょう。
まず、以下のコマンドでサーバー版Ubuntu 24.04.1のISOイメージと、チェックサムが書かれたファイルをダウンロードします。
$ wget http://ubuntutym2.u-toyama.ac.jp/ubuntu/24.04.1/ubuntu-24.04.1-live-server-amd64.iso $ wget http://ubuntutym2.u-toyama.ac.jp/ubuntu/24.04.1/SHA256SUMS
以下のように「-c」オプションと引数にSHA256SUMSファイルを指定してコマンドを実行します。なお、SHA256SUMSファイルにはデスクトップ版とサーバー版両方のISOイメージファイルのチェックサムが記述されています。今回の例ではデスクトップ版のISOイメージファイルはダウンロードしていないため、警告が表示されてしまいます。それを抑制するため「--ignore-missing」オプションも付けておくと良いでしょう。
$ sha256sum -c --ignore-missing SHA256SUMS ubuntu-24.04.1-live-server-amd64.iso: OK
上記のように、ファイル名の後に「OK」と表示されれば検証は完了です。インターネットからダウンロードしたファイルは、念のためチェックサムを用いて破損や改竄がないか確認すると良いでしょう。
ファイルの行数、文字数、バイト数を出力する「wc」
wcコマンドは、ファイルの行数、文字数、バイト数をカウントして出力します。以下はexample.txtの行数、文字数、バイト数をカウントする例です。
$ wc example.txt
なお「-l」オプションを付けると、このうち行数のみを出力します。これを利用して他のコマンドの結果をパイプし、項目数をカウントする目的で使うこともよくあります。例えば、以下はerror.logというログファイルからERRORという文字列が含まれる行を検索し、その行数をカウントすることで発生したエラーの件数を数えています。
$ grep 'ERROR' error.log | wc -l
ファイルを編集/変換/ソートするコマンド
BASE64エンコード/デコードを行う「base64」
base64は、BASE64のエンコードとデーコドを行うコマンドです。最近ではデータをBASE64エンコードして環境変数にセットしたり、逆にJSONで取得したデータの中身がBASE64エンコード済みだったりといったケースもよくあるでしょう。そうしたデータを作る/読む際に便利です。以下は「hello」という文字列をBASE64エンコードして「aGVsbG8K」というエンコード結果を得る例です。
$ echo 'hello' | base64 aGVsbG8K
「-d」オプションを付けると、逆にBASE64エンコードされたデータをデコードします。先ほど得られた「aGVsbG8K」というエンコード済みの文字列をデコードするには、以下のようにコマンドを実行します。
$ echo 'aGVsbG8K' | base64 -d hello
ファイルの中身をシャッフルする「shuf」
shufコマンドはファイルの中身を行単位でシャッフルした結果を表示します。以下は、example.txtの中からランダムな一行を取り出す例です。shufコマンドでファイルをかき混ぜてから、headコマンドで先頭の1行取り出すことで実現しています。
$ shuf example.txt | head -n1
ファイルの中身をソートする「sort」
sortはファイルの中身を行単位でソートするコマンドです。後述するuniqのように、Linuxコマンドの中には元ファイルがソート済みであることを前提としているものも多く存在します。そうしたコマンドを実行する前処理としてもよく使われるコマンドです。以下は、example.txtをソートする例です。
$ sort example.txt
よく併用されるオプションとして、文字列ではなく数値としてソートする「-n」オプション、逆順に表示する「-r」オプション、ソートした上で重複行を削除する「-u」オプションなどがあります。また、ソフトウェアのバージョン番号や月の名前などを正しくソートすることもできます。
文字の置換と削除を行う「tr」
trは文字の置換と削除を行うコマンドです。以下は「hello」という文字列を大文字に変換する例です。なお、trコマンドはファイルを直接開けないため、別のコマンドの出力をパイプして読み込む必要があります。
$ echo 'hello' | tr '[:lower:]' '[:upper:]' HELLO
「-d」オプションを付けると、指定した文字を削除できます。以下はexample.txtから改行を削除します。
$ cat example.txt | tr -d '\n'
ファイルから重複を削除する「uniq」
ファイルから重複した行を削除します。なお、この際に元のファイルはあらかじめソート済みである必要があります。そのためsortコマンドと組み合わせて使うのが一般的ですが、前述の通りsortコマンドにはuniqコマンドと同様の動作をする「-u」オプションが存在するため、重複を削除するだけであればuniqコマンドの出番はあまりないかもしれません。以下の2つのコマンドは、どちらも同じ結果となります。
$ sort example.txt | uniq $ sort -u example.txt
uniqコマンドには、重複した件数をカウントする「-c」オプションが存在します。このオプションを使うと、例えばWebサーバーのアクセスログから、アクセス数が多いページのランキングを作るといったこともできます。
ファイルやディレクトリに関するコマンド
ファイルやディレクトリをコピーする「cp」
ファイルやディレクトリをコピーする、Linuxにおいて基本中の基本とも言えるコマンドがcpです。最も基本的な使い方は、1番目の引数に指定したファイルを、2番目の引数に指定したファイルとしてコピーすることです。例えば、以下はexample.txtというファイルをcopy.txtというファイルにコピーします。
$ cp example.txt copy.txt
ディレクトリをコピーするときは「-r」オプションを併用します。以下は、srcdirというディレクトリをdestdirという名前でコピーします。なお、この際にdestdirというディレクトリが既に存在した場合は、その中にsrcdirがコピーされます。このように、同じコマンドでも状況によって結果が異なることがあります。
$ cp -r srcdir destdir
複数のファイルをまとめてディレクトリにコピーすることもできます。cpコマンドは絶対にマスターすべきコマンドな上、非常に多くのオプションや使い方があるため、ぜひmanページを熟読してください。
ファイルのコピーと変換を行う「dd」
ddコマンドは、ファイルのコピーと変換を行います。主に単なるファイルのコピーよりも、USBメモリにISOファイルを書き込んだり、ディスク全体をゼロで上書きしたりする際によく利用されます。例えば、以下のように実行するとUbuntuのISOイメージファイルをUSBメモリに書き込んで、インストールメディアを作ることができます。
$ sudo dd if=ubuntu-24.04.1-live-server-amd64.iso of=USBメモリのデバイスファイル名 bs=1M
「conv」オプションを指定すると、コピー中にファイルの中身を変換できます。以下はexample.txtをoutput.txtとしてコピーする例ですが、「conv=ucase」が指定されているため、テキストファイル中のアルファベット小文字が、すべて大文字に変換されてコピーされます。
$ dd if=example.txt of=output.txt conv=ucase
属性を指定してコピーする「install」
Linuxシステムの管理においては、ファイルやディレクトリをシステムの領域にコピーした上で、所有者やパーミッションを適切なものに変更する場合がよくあります。前述したcpコマンドでコピーを行った後に、後述するchownコマンドやchmodコマンドで所有者やパーミッションを変更するのが一般的ですが、これを同時に行えるのがinstallコマンドです。
引数にコピー元ファイルとコピー先ファイルを指定する点は、cpコマンドと同じです。その際に「-o」オプションで所有者、「-g」オプションでグループ、「-m」オプションでパーミッションを指定できます。以下は、script.shというスクリプトファイルで所有者をroot、グループをubuntu、パーミッションを755として/usr/local/binディレクトリにコピーする例です。
$ sudo install -o root -g ubuntu -m 755 script.sh /usr/local/bin/script.sh
また「-d」オプションを指定すると、その属性でディレクトリを作成できます。この際は、コピー元ファイルの指定は不要です。作成するディレクトリ名のみを指定してください。
リンクを作成する「ln」
lnコマンドは、あるファイルにハードリンクを作成します。ハードリンクとは、同じファイルシステム上に作られたファイルの別名です。以下は、example.txtにlink.txtという別名を作成する例です。以後、example.txtとlink.txtは同一のファイル(の実体)を指すようになります。
$ ln example.txt link.txt
lnコマンドに「-s」オプションを付けると、ハードリンクではなくシンボリックリンクを作成できます。シンボリックリンクもハードリンクと同様に、あるファイルに付けられた別名です。ハードリンクがファイルシステム上のi-nodeと呼ばれるメタ情報を元にリンクを辿るのに対し、シンボリックリンクはパスを頼りにリンクを辿ります。
ハードリンクはファイルシステム上のメタ情報を元にリンクを辿るため、リンク先のファイルの名前を変えたりディレクトリを移動してもリンクが切れません。その反面、ファイルシステムを跨いでリンクを作成できないという特徴があります。シンボリックリンクはその逆で、ファイルシステムを跨いでリンクを作れる反面、リンク先の名前(パス)が変わるとリンクが切れてしまうという特徴があります。用途に応じて使い分けてください。
ディレクトリの内容を表示する「ls」
ディレクトリの中にあるファイルの一覧を表示するのがlsコマンドです。おそらくLinuxのCLIにおいて、世界で一番多く実行されているコマンドではないでしょうか。
よく使うオプションとして、隠しファイルを表示する「-a」オプション、詳細なリスト表示をする「-l」オプション、時系列に並び変える「-t」オプション、逆順で表示する「-r」オプション、数値を読みやすく表示する「-h」オプション(-lオプションと併用)などがあります。以下は、ホームディレクトリの中身を、隠しファイルも含め古い順に詳細なリスト表示をする例です。
$ ls -ltar ~
lsコマンドは基本中の基本の上、便利なオプションが色々とあるため、一度はmanを読んでみてください。
ディレクトリを作成する「mkdir」
新しいディレクトリを作成するのがmkdirコマンドです。引数に作成したいディレクトリ名を指定してください。なお「-p」オプションを指定すると、親ディレクトリが存在しなかった場合は、親ディレクトリも含めて一気に作成できます。
以下は、ホームディレクトリ内に「~/work/wsl/document」という階層のサブディレクトリを作成する例です。-pオプションが指定されているため、「work」ディレクトリや「work/wsl」ディレクトリが存在しなかった場合は同時に作成されます。
$ mkdir -p ~/work/wsl/document
ファイルを移動する「mv」
ファイルやディレクトリを移動するのがmvコマンドです。cpコマンドと同様に、移動元のファイル名と移動先のファイル名を引数に指定して使います。以下は、example.txtというファイルをworkディレクトリ内に移動する例です。
$ mv example.txt work/example.txt
副次的な使い方として、ファイルの名前の変更があります。ファイルの名前の変更とは、同じディレクトリ内で(別名のファイルとして)移動を行っていることに他なりません。例えば、以下はexample.txtの名前をrenamed.txtに変更しています。
$ mv example.txt renamed.txt
複数のファイルを同時に移動することもできますが、この場合は移動先の名前を個別に指定できないため、移動先は既存のディレクトリに限られ、かつファイル名を同時に変更できません。cpコマンド同様に引数の指定の仕方にはいくつかのパターンがあり、それによって挙動が微妙に変化するため一度はmanを読んでおきましょう。
ファイルを削除する「rm」
ファイルを削除するのがrmコマンドです。削除したいファイルを引数に指定して使います。ファイルは複数指定することもできます。以下は、example1.txtとexample2.txtという2つのファイルを削除する例です。
$ rm example1.txt example2.txt
rmコマンドではディレクトリを削除できませんが、「-r」オプションを付けることでディレクトリとその中身を再帰的に削除できます。以下は、workというディレクトリと、その中身をすべて削除する例です。
$ rm -r work
なお、CLIにはゴミ箱がないため、うっかり間違ったディレクトリを削除してしまうと大事故に繋がります。ディレクトリを削除するときは、くれぐれも注意してください。
ディレクトリを削除する「rmdir」
ディレクトリを削除するコマンドがrmdirです。中身ごと消す「rm -r」コマンドと違い、rmdirコマンドはディレクトリの中身が空でないと失敗します。例えば、以下はworkディレクトリを削除する例ですが、workディレクトリ内にファイルが1つでも残っていると、このコマンドはエラーになります。
$ rmdir work
前述の通り「rm -r」による削除は大事故を起こす可能性があります。重要なサーバー上で作業を行うような場合は、ディレクトリは親ごと一気に削除することは避け、確認しながら個別にファイルを削除し、中身が空になったことを確認してからrmdirコマンドを使うことを推奨します。
カレントディレクトリを表示する「pwd」
pwdはカレントディレクトリを表示するコマンドです。単体ではそれほど意味のあるコマンドではありませんが、別のコマンドにディレクトリのパスを引き渡したいような場合によく使われます。
具体的な例を挙げて説明しましょう。Dockerでコンテナを起動する際に、カレントディレクトリをワーキングディレクトリとしてコンテナ内にマウントしたいというケースがありますが、カレントディレクトリは環境によって異なるため、スクリプトなどにハードコーディングできません。そこでpwdコマンドを使うと環境による違いを吸収し、コマンドを一般化できます。以下のdockerコマンドは、カレントディレクトリをコンテナ内の「/var/lib/work」にマウントする例です。
$ sudo docker run -v $(pwd):/var/lib/work container-name
ファイルやディスクを安全に消去する「shred」
rmコマンドでファイルを削除してもディスク上には0と1のデータの羅列が残っており、やり方によってはデータを復元できますが、機密データを破棄するような場合には都合が悪いでしょう。shredコマンドは、ファイルやディスクを安全に消去するコマンドです。
以下は、example.txtというファイルをshredコマンドで削除する例です。「-v」オプションを付けることで詳細な進捗が表示されます。ここから分かる通り、ファイル上に3回ランダムなデータを上書きしてから削除を行っています。
$ shred example.txt shred: example.txt: pass 1/3 (random)... shred: example.txt: pass 2/3 (random)... shred: example.txt: pass 3/3 (random)...
削除対象にディスクのデバイスファイルを指定することで、HDDやSSD全体を消去することもできます。また「-z」オプションを付けると、乱数を書き込んだ後に全体にゼロを上書きします。NSA(米国家安全保障局)では、データを消去する際はディスク全体に2回乱数を書き込んだ後でゼロを書き込むことを推奨しています。これをshredコマンドで実行するには、回数を指定する「-n」オプションと「-z」オプションを組み合わせて、以下のように実行します。
$ sudo shred -v -n 2 -z /dev/ディスクのデバイスファイル名
ファイルの属性を変更するコマンド
ファイルの所有グループを変更する「chgrp」
Linuxにおいて、ファイルやディレクトリには所有者と所有グループが設定されています。そして所有者、所有グループ、その他の第三者それぞれにアクセス権限が設定されています。chgrpはそのうち、所有グループを変更するためのコマンドです。引数に変更後のグループ名と対象のファイルを指定して実行します。
$ chgrp ubuntu example.txt
ただし、上記のように所有グループが変更できるのは、対象のファイルを自分自身が所有しており、変更後の所有グループにも自分が所属している場合に限ります。それ以外のファイルの所有グループを変更するにはroot権限(sudo)が必要となるので注意してください。
なお「-R」オプションを付けてディレクトリを指定すると、ディレクトリ内のファイルとサブディレクトリに再帰的に変更を適用できます。
ファイルのパーミッションを変更する「chmod」
Linuxのファイルには所有者、所有グループ、第三者それぞれに「読み込み」「書き込み」「実行」の3つの権限が個別に設定されています。これをパーミッションと呼びます。そしてchmodはファイルのパーミッションを変更するためのコマンドです。
設定するパーミッションは、数値とシンボルによる指定が可能です。よく目にするのが「読み込み」「書き込み」「実行」をそれぞれ二進数のフラグに置き換え、それを8進数に変換して表す方式です。例えば、以下のコマンドはexample.txtのパーミッションを644、すなわち所有者は読み書き可能、所有グループと第三者は読み込みのみ可能に設定します。
$ chmod 644 example.txt
数値の具体的な意味については、以下のコマンドでmanセクション2のchmodシステムコールを参照してください。
$ man 2 chmod
シンボルモードは読み込み(r)、書き込み(w)、実行(x)のパーミッションを、所有者(u)、所有グループ(g)、第三者(o)、すべてのユーザー(a)の誰に設定するかを文字で指定するモードです。また、これ以外にもSETUIDとSETGIDという特殊なビットや、削除制限フラグやスティッキービットといった属性を設定できます。ここではこれらの解説を省略するので、詳しくはchmodのmanページを参照してください。
ファイルの所有者を変更する「chown」
chgrpコマンドがグループのみであったのに対し、chmodコマンドはファイルの所有者と所有グループの両方を変更するコマンドです。基本的な使い方はchgrpコマンドと同様ですが、所有者と所有グループを「:」もしくは「.」で区切って指定する点が異なります。また、所有者を変更するため、実行にはroot権限が必要となります。以下はexample.txtの所有者をroot、所有グループをubuntuに設定する例です。
$ sudo chmod root:ubuntu example.txt
なお「:」の前部分を省略することで、chgrpと同様に所有グループだけを変更することもできます。
ファイルのタイムスタンプを変更する「touch」
touchコマンドは、引数に指定したファイルのタイムスタンプを変更するコマンドです。以下は、example.txtのタイムスタンプを現在時刻に変更する例です。前後でlsコマンドを実行してみると、タイムスタンプが変更されていることが確認できます。
$ ls -l example.txt -rw-rw-r-- 1 mizuno mizuno 4096 1月 15 14:55 example.txt $ touch example.txt $ ls -l example.txt -rw-rw-r-- 1 mizuno mizuno 4096 1月 15 16:57 example.txt
なお、存在しないファイルを指定すると、その名前で空のファイルを作成します。どちらかと言うと、こちらの目的で利用されることが多いため、空ファイルを作成するコマンドだと誤解されているかもしれません。
ユーザーとシステムに関するコマンド
システムのアーキテクチャを表示する「arch」
archはシステムのアーキテクチャ(x86_64やarm64など)を表示するコマンドです。アーキテクチャによって動作するバイナリは異なります。最近ではx86_64だけでなく、armアーキテクチャのCPUが使われるサーバーも増えてきたので、現在のシステムのアーキテクチャを確認する必要に迫られることも多いのではないでしょうか。また、インストールスクリプトの中などで、アーキテクチャによりインストールするパッケージを切り替えるといった用途にも利用できます。
$ arch x86_64
時刻を表示する「date」
dateコマンドは、文字通り時刻を表示するコマンドです。引数なしで実行すると現在の時刻を表示します。
$ date 2025年 1月 15日 水曜日 16:33:27 JST
「-d」オプションを使うことで、任意の時刻を非常に柔軟に指定することもできます。以下のコマンドは、現在の3日後の時刻を表示する例です。
$ date -d '3 days' 2025年 1月 18日 土曜日 16:34:03 JST
「+」に続いてフォーマット指示子を指定することで、出力フォーマットを指定することもできます。以下は、次の日曜日(next sunday)の日付を「YYYY/MM/DD」のフォーマットで表示する例です。
$ date -d 'next sunday' '+%Y/%m/%d' 2025/01/19
dateはこうした性質を利用し、時刻を元にした文字列を組み立てることに使われることもよくあります。
所属しているグループ名を表示する「groups」
groupsコマンドは、引数に指定したユーザーが所属しているグループ名を表示します。引数を省略した場合は自分自身の情報を表示します。
$ groups mizuno adm dialout cdrom floppy sudo audio dip video plugdev users netdev
ユーザーIDやグループIDを表示する「id」
idコマンドは、引数に指定したユーザーのユーザーIDや所属するグループIDを表示します。引数を省略すると自分自身の情報を表示します。Linuxではグループごとに権限が分けられており、特定のグループに所属しないと行えない処理も存在します。例えば、Ubuntuではsudoコマンドはsudoグループに所属していなければ使えません。そうした場合の所属グループの確認などに利用できます。
$ id uid=1000(mizuno) gid=1000(mizuno) groups=1000(mizuno),4(adm),20(dialout),24(cdrom),25(floppy),27(sudo),29(audio),30(dip),44(video),46(plugdev),100(users),107(netdev)
なお、名前を表示する「-n」オプションと、すべてのグループIDを表示する「-G」オプションを併用すると、前述のgroupsコマンドと同じ挙動になります。
$ id -n -G
システム情報を表示する「uname」
unameはシステム情報を表示するコマンドです。オプションなしで実行すると、システム名(Linux環境であればLinux、macOSであればDarwinなど)のみを表示します。「-m」オプションでアーキテクチャ(x86_64やarm64など。archコマンドと同じ挙動になる)、「-r」オプションでカーネルのリリース、「-v」オプションでカーネルのバージョンを表示します。
「-a」オプションを付けるとすべての情報を表示するため、対話的に利用するのであれば、こちらを利用しておけば良いでしょう。以下はWSLのUbuntu 24.04でunameコマンドを実行した例ですが、WSLのカーネル上で動いているためカーネルのリリースが「microsoft-standard-WSL2」となっていることが分かります。
$ uname -a Linux kitalpha 5.15.167.4-microsoft-standard-WSL2 #1 SMP Tue Nov 5 00:21:55 UTC 2024 x86_64 x86_64 x86_64 GNU/Linux
また、システム名を表示できるため、このコマンドをスクリプトの中で利用してLinuxとmacOSで処理を分岐するインストールスクリプトを実装するといったこともできます。
システムの稼動時間を表示する「uptime」
uptimeコマンドは現在時刻、システムが起動してからの時間、ログインユーザー数、ロードアベレージを表示するコマンドです。この中でも特に重要なのが、システムが起動してからの時間です。これはシステムが動き続けている限り常に増え続け、減ることはありません。そのため、この値が減少していればシステムが意図せず再起動したことを意味します。サーバーが再起動した疑いがあるときは、このコマンドを実行してみましょう。
以下は、uptimeコマンドの実行例です。このサーバーは起動してから9日ほど経過していることが分かります。
$ uptime 15:25:40 up 9 days, 4:51, 1 user, load average: 0.01, 0.04, 0.00
ログイン中のユーザー情報を表示する「who」
whoコマンドはシステムにログイン中のユーザー情報を表示します。ログイン中のユーザー名とあわせて、ログイン時刻と使用している仮想端末、リモートから接続している場合はIPアドレスも表示されます。
$ who mizuno pts/0 2025-01-15 15:47 (192.168.1.101)
「-b」オプションを付けると、最後にシステムが起動した時刻を表示します。
$ who -b system boot 2025-01-06 10:34
自分のユーザー名を表示する「whoami」
whoamiコマンドは自分のユーザー名を表示します。対話的にLinux環境にログインしているのであれば、自分のユーザー名が分からなくなるということはあまりないでしょう。これも前述のpwdコマンドと同様に、スクリプト内に埋め込んでユーザーや環境によって異なるパラメータを抽象化するような際に利用されることが多いコマンドです。
$ whoami mizuno
プロセスに関するコマンド
プロセスにシグナルを送る「kill」
実行中のプロセスは「シグナル」という仕組みを用いて様々なイベントの発生を通知します。プロセスはシグナルを受信すると、そのシグナルの種類に応じて一時停止、再開、終了といった処理を行います。そしてプロセスに任意のシグナルを送れるコマンドがkillです。
killコマンドは、送信するシグナルの種類と送信先のプロセスIDを指定して使います。例えば、以下はプロセスIDが1000のプロセスにKILLシグナル(強制終了)を送信しています。
$ kill -KILL 1000
暴走したプロセスを強制終了する最後の手段として、KILLシグナルの送信はよく使われます。覚えておくと良いでしょう。なお、シグナルについての詳しい解説は、以下のコマンドでmanセクション7の「signal」を参照してください。
$ man 7 signal
処理を一時停止する「sleep」
複数のコマンドを連続して実行していると、コマンドとコマンドの間にインターバルを設けたい場合がよくあります。sleepは指定した時間の間、処理を一時停止するコマンドで、主にシェルスクリプトの中で利用されます。引数に停止したい時間を指定して実行してください。以下のコマンドは、60秒間処理を一時停止する例です。
$ sleep 60
数字の後には「s」「m」「h」「d」というサフィックスを付けることができ、それぞれ「秒」「分」「時間」「日」を表します。サフィックスを省略した場合は「s」が指定されたものとして扱われます。例えば、60秒のスリープは以下のように書くこともできます。
$ sleep 1m
タイムアウトを指定してコマンドを実行する「timeout」
timeoutは単独で使うコマンドではなく、別のコマンドにタイムアウトを設定するためのコマンドです。例えば、yesコマンドは「y」という文字を出力するコマンドですが、[Ctrl]キー+[C]キーが押されるまで無限に実行を続けます。timeoutを設定して実行すれば、指定した時間が経過した時点で自動的にコマンドの実行を打ち切ることができます。以下のコマンドを実行すると3秒間だけyesコマンドが実行され、タイムアウトを迎えると自動的に終了します。
$ timeout 3 yes
おわりに
駆け足でしたが、Coreutilsに含まれるコマンドのうち、41個のコマンドの概要を紹介しました。どんな環境にもインストールされているであろう基礎コマンドで、ここまで色々なことができるのかと驚いた方も多いのではないでしょうか。
しかし、冒頭にも述べた通り、これでもまだ含まれるコマンドのうちの半分以下に過ぎません。本記事では省略しましたが、他にも数値の単位を変換する「numfmt」コマンド、2つのデータを比較して出力する「comm」コマンド、表の結合に使える「paste」コマンドや「join」コマンド、因数分解をする「factor」コマンドなど、様々なコマンドが用意されています。
LinuxのCLIはコマンドを組み合わせて使用するため、どれだけ多くのコマンドを知っているかは英語で言えば単語力に相当する基礎であると筆者は考えています。必要になったときにマニュアルを読めば良いのですから、すべてのコマンドの使い方を暗記する必要はありませんが、「こういう機能のコマンドが存在する」ということを知っておくのはLinux力を上げるうえで重要なのではないでしょうか。
本記事を読んで興味を持ったら、Coreutilsのマニュアルの目次だけでも目を通しておくと、いざというときの力になるかもしれません。
次回は、より快適なCLI環境を構築するための、シェルのカスタマイズについて解説します。