第7章 コマンドラインの応用操作
LPIC-1 103.1 相当
シェルをより効率よく使うための、少し進んだコマンドライン操作を扱います。LPICでは103.1として出題される範囲です。
環境変数
環境変数は、シェルやその配下のプログラムが参照できる名前付きの値です。PATH(コマンド検索先のディレクトリ一覧)はその代表例です。
$ echo $HOME # 変数の中身を表示
/home/user
$ echo $PATH
/usr/local/bin:/usr/bin:/bin
$ export MY_VAR="hello" # 環境変数として設定(子プロセスにも引き継がれる)
$ env # 現在の環境変数を一覧表示
HOME=/home/user
PATH=/usr/local/bin:/usr/bin:/bin
MY_VAR=hello
SHELL=/bin/bash
...(この後も環境変数が続く)
この行のこの値に注目: envの一覧にMY_VAR=helloが含まれていれば、直前のexportで設定した変数が正しく環境変数として登録され、これ以降に起動する子プロセスにも引き継がれる状態になっていることが確認できます。
クォーティング(引用符)の違い
| 記法 | 動作 |
|---|---|
シングルクォート '...' | 中身をすべて文字どおり扱う(変数展開されない) |
ダブルクォート "..." | 変数展開やコマンド置換は行われる |
バックスラッシュ \ | 直後の1文字だけを特殊文字として扱わせない(エスケープ) |
$ name="World"
$ echo 'Hello $name'
Hello $name
$ echo "Hello $name"
Hello World
コマンド置換
$(コマンド) と書くと、そのコマンドの実行結果を文字列として埋め込めます。
$ echo "今日の日付は $(date +%Y-%m-%d) です"
今日の日付は 2026-08-13 です
コマンド履歴の活用
| 操作 | 意味 |
|---|---|
history | これまでに実行したコマンドの一覧を表示 |
!! | 直前に実行したコマンドをもう一度実行 |
!123 | historyの123番目のコマンドを再実行 |
| Ctrl+R | 過去のコマンドをインクリメンタル検索 |
コマンドの実体を調べる
あるコマンド名が「何であるか」(外部コマンドか、シェル組み込みか、エイリアスか)を調べる手段があります。
| コマンド | 役割 |
|---|---|
type コマンド名 | コマンドの種類(エイリアス・組み込み・外部コマンドなど)を判定 |
which コマンド名 | PATH上にある外部コマンドの実際のパスを表示 |
alias | 現在定義されているエイリアスの一覧を表示 |
unalias 名前 | エイリアスを解除 |
$ type cd
cd is a shell builtin
$ type ls
ls is aliased to `ls --color=auto'
$ which python3
/usr/bin/python3
ワイルドカードとブレース展開
シェルはコマンドを実行する前に、行内の特殊な記法をいくつかの段階で展開します。これを理解しておくと、意図しない挙動に悩まされにくくなります。
| 記法 | 展開結果 |
|---|---|
* | 0文字以上の任意の文字列にマッチ(globbing) |
? | 任意の1文字にマッチ |
[abc] | a・b・cのいずれか1文字にマッチ |
{a,b,c} | ブレース展開。a・b・cそれぞれに展開される(マッチではなく生成) |
$ echo file{1,2,3}.txt
file1.txt file2.txt file3.txt
$ ls *.log
access.log error.log system.log
この行のこの値に注目: echo file{1,2,3}.txtは実際にそのファイルが存在するかどうかに関係なく3つの文字列を生成しますが、ls *.logは既存の.logファイルの中から実際にマッチしたものだけが表示されます。該当ファイルが1つもなければ「そのようなファイルはありません」というエラーになる点が、ブレース展開との大きな違いです。
*など)は「既存のファイル名にマッチするか」で展開されるのに対し、ブレース展開({a,b,c}のような記法)はファイルの存在に関係なく文字列を機械的に生成する点が異なります。
コマンドの終了ステータス
すべてのコマンドは終了時に「終了ステータス」という数値を返します。慣習として、0は成功、0以外は何らかの失敗を意味します。この値は特殊変数$?で直前のコマンドの結果を確認できます。
$ ls /etc/passwd
/etc/passwd
$ echo $?
0
$ ls /no/such/file
ls: cannot access '/no/such/file': No such file or directory
$ echo $?
2
これを利用して、直前のコマンドの成否によって次に実行する内容を変える制御記法もあります。
| 記法 | 意味 |
|---|---|
cmd1 && cmd2 | cmd1が成功(終了ステータス0)したときだけcmd2を実行 |
cmd1 || cmd2 | cmd1が失敗したときだけcmd2を実行 |
cmd1 ; cmd2 | 成否にかかわらず順番に実行 |
エイリアスの作成と設定ファイル
aliasを使うと、よく使うコマンドに短い別名を付けられます。ただし、そのままではシェルを終了すると忘れられてしまうため、恒久的に使いたい場合は設定ファイルに記述します。
$ alias ll='ls -alF' # その場限りのエイリアス定義
$ echo "alias ll='ls -alF'" >> ~/.bashrc # 恒久化するには設定ファイルに追記する
| ファイル | 読み込まれるタイミング |
|---|---|
/etc/profile | ログインシェル起動時、システム全体に対して読み込まれる |
~/.bash_profile / ~/.profile | ログインシェル起動時、ユーザー個別に読み込まれる |
~/.bashrc | 対話的な非ログインシェル(新しい端末を開いたときなど)で読み込まれる |
ヒアドキュメント
複数行にわたるテキストをコマンドの標準入力として渡したいとき、<<を使う「ヒアドキュメント」という記法が便利です。
$ cat << EOF > memo.txt
これは1行目
これは2行目
EOF
指定した終端文字列(上の例ではEOF、任意の文字列でよい)が単独で現れるまでの内容が、まとめてコマンドに渡されます。設定ファイルの雛形をスクリプトから生成する際などによく使われます。
シェルスクリプトのデバッグ
シェルスクリプトが期待通りに動かないときは、実際にどのコマンドがどう展開されて実行されたかを表示させると原因を追いやすくなります。
$ bash -x script.sh # スクリプト実行中、各行の展開後の内容を + 付きで表示しながら実行
+ name=World
+ echo 'Hello World'
Hello World
+ ls memo.txt notes.txt
memo.txt
+ ls: cannot access 'notes.txt': No such file or directory
$ set -x # 対話シェル・スクリプト内でデバッグモードを有効化
$ set +x # デバッグモードを無効化
この行のこの値に注目: 行頭の+が付いた行が、実際にシェルが実行したコマンドのトレースです。echo 'Hello World'のように変数展開後の実際の値が表示されるため、ls memo.txt notes.txtの直後に出ているエラーから「notes.txtというファイルが存在しない」という具体的な失敗箇所をその場で特定できます。
bash -xの出力では、変数展開やコマンド置換が済んだ「実際にシェルが実行しようとしている形」がそのまま表示されるため、「変数の中身が空だった」「意図しないファイル名に展開されていた」といった、頭の中で追うだけでは気づきにくい原因を見つけやすくなります。長いスクリプトの一部分だけをデバッグしたい場合は、該当箇所の直前にset -x、直後にset +xを挟むことで、出力される範囲を絞り込めます。
シェル変数と環境変数の違い
変数を扱ううえで混同しやすいのが「シェル変数」と「環境変数」の違いです。単にNAME=valueと代入しただけのものはシェル変数で、そのシェル自身の中でしか参照できません。一方、export NAME=valueのようにexportした変数は環境変数となり、そのシェルから起動した子プロセス(別のスクリプトやコマンドなど)にも値が引き継がれます。「スクリプトの中で設定した変数が、呼び出した別のプログラムから見えない」という不具合に出会ったら、exportし忘れていないかをまず疑ってみましょう。