閉じる

Bashで直前の引数を再利用する! !$ の便利な使い方と活用テクニック

LinuxやmacOSのターミナルで作業をしていると、直前に入力したコマンドの引数をそのまま使い回したい場面が頻繁に発生します。

例えば、ディレクトリを作成した直後にそのディレクトリへ移動したり、長いパスにあるファイルを編集した後にそのファイルを別の場所へコピーしたりする場合です。

このような作業でパスを再度入力したり、マウスでコピー&ペーストしたりするのは非常に手間がかかり、打ち間違いの原因にもなりかねません。

Bashには、こうした手間を劇的に減らすための「!$」という便利な特殊記号(イベント指示子)が用意されています。

この記事では、Bashにおける「!$」の基本的な使い方から、より高度な活用テクニックまで、実務で役立つ知識を詳しく紹介します。

Bashの「!$」とは何か

「!$」は、Bashの「ヒストリ展開(History Expansion)」と呼ばれる機能の一部です。

具体的には、「直前に実行したコマンドの最後の引数」を指し示す役割を持っています。

例えば、ls /var/log/nginx というコマンドを実行した直後に cd !$ と入力すると、cd /var/log/nginx を実行したことと同じ意味になります。

この機能はターミナル上での対話的な操作において、入力の手間を大幅に削減し、オペレーションのスピードを向上させるために欠かせないものです。

基本的な使用例:ディレクトリ作成と移動

最も一般的で分かりやすい例は、ディレクトリの作成と、その中への移動をセットで行うケースです。

通常であれば、以下のように同じパスを2回入力する必要があります。

Shell
# 通常の入力方法
mkdir /home/user/work/project_2026_data
cd /home/user/work/project_2026_data

ここで「!$」を活用すると、2行目の入力を次のように簡略化できます。

Shell
# !$ を活用した入力方法
mkdir /home/user/work/project_2026_data
cd !$
実行結果
cd /home/user/work/project_2026_data

実行した瞬間に、Bashは自動的に「!$」を直前の引数である /home/user/work/project_2026_data に置き換えて実行します。

長いディレクトリ名であればあるほど、この機能の恩恵を強く感じることができるでしょう。

ファイル操作における活用

ファイルの閲覧や編集の際にも、「!$」は非常に有効です。

例えば、設定ファイルの内容を確認した後に、そのファイルを編集したいといったシナリオが考えられます。

Shell
# まずは cat で内容を確認
cat /etc/nginx/conf.d/default.conf

# 内容を確認したので、vi で編集を開始する
vi !$

このように、直前の対象物(引数)に対して異なるアクション(コマンド)を実行したい場合に、スムーズに作業を移行できます。

「!$」と類似する機能の比較

Bashには「!$」以外にも、直前のコマンドや引数を参照する方法がいくつか存在します。

それぞれの違いを理解しておくことで、状況に応じた最適な使い分けが可能になります。

「$_」変数との違い

「!$」と非常によく似たものに、$_(アンダースコア)という特殊変数があります。

両者はどちらも「直前のコマンドの最後の引数」を指しますが、評価されるタイミングが異なります。

機能種類特徴
!$ヒストリ展開実行ボタン(Enter)を押した瞬間に展開され、コマンドライン上に履歴として残る。
$_シェル変数シェルの内部変数として保持される。スクリプト内でも利用可能。

ターミナルでの作業中に、実際に実行されるコマンドを視覚的に確認したい場合は「!$」が適しています。

一方で、シェルスクリプトの中で動的に最後の引数を利用したい場合は $_ を使うのが一般的です。

ショートカットキー「Alt + .」の活用

コマンドを打ち込む手間を省くという意味では、キーボードショートカットの Alt + . (または Esc を押した後に .)も強力です。

このショートカットを押すと、現在入力中の場所に直前の引数が即座に挿入されます。

「!$」との最大の違いは、「実行前に引数を確認・修正できる」点にあります。

もし直前の引数の一部を書き換えて実行したい場合は、ショートカットキーで一度文字を展開してから編集するのが効率的です。

「!$」をより便利にする修飾子(Modifiers)

Bashのヒストリ展開には、取得した文字列を加工するための「修飾子」という機能があります。

「!$」と組み合わせることで、パスの一部だけを抽出するといった高度な操作が可能になります。

「:h」でディレクトリ部分のみを取得する

:h(head)修飾子を使用すると、パスからファイル名を取り除き、親ディレクトリのパスだけを取得できます。

Shell
# ファイルを指定して作業
ls /usr/local/bin/my_script.sh

# そのファイルがあるディレクトリに移動したい場合
cd !$:h
実行結果
cd /usr/local/bin

深い階層にあるファイルを操作した後、その周辺のファイルを確認したいときに非常に便利です。

「:t」でファイル名のみを取得する

逆に、:t(tail)修飾子を使用すると、ディレクトリパスをすべて切り捨てて、ファイル名や末尾のディレクトリ名だけを取得できます。

Shell
# 遠くのディレクトリにあるファイルをコピー
cp /tmp/download/very_long_name_data.csv .

# そのファイルの名前を使って別の操作(例:名前変更)
mv !$ !$:t.old
実行結果
mv very_long_name_data.csv very_long_name_data.csv.old

このように、複雑なパス指定を省略しつつ、ファイル名だけを再利用して別の作業を行うことができます。

「:r」で拡張子を取り除く

:r(root)修飾子を使うと、ファイル名から拡張子を取り除いた部分を取得できます。

Shell
# 圧縮ファイルを解凍
gunzip data_log.tar.gz

# 拡張子を除いた名前でディレクトリを作成
mkdir !$:r
実行結果
mkdir data_log.tar

複数の修飾子を組み合わせて、!$:r:r のように記述することで、多重の拡張子を段階的に取り除くことも可能です。

実践的なテクニックと注意点

「!$」を使いこなすために、いくつか知っておくべき実践的なポイントがあります。

複数の引数がある場合の挙動

「!$」はあくまで「最後の」引数を参照します。

例えば cp file1.txt file2.txt /backup/ というコマンドを実行した場合、「!$」が指すのは /backup/ です。

もし file1.txt を参照したい場合は、!^(最初の引数)や !:1(1番目の引数)といった別の記法を使う必要があります。

ヒストリ展開が無効な環境

通常、デスクトップPCやサーバーのBashではヒストリ展開が有効になっていますが、一部の環境やシェルスクリプト内では無効化されていることがあります。

もし「!$」と入力しても展開されず、そのまま「!$」という文字列として扱われてしまう場合は、以下のコマンドで有効化できます。

Shell
set -H

逆に、スクリプト内など意図しない展開を防ぎたい場合は set +H で無効化できますが、基本的には対話型シェルでのみ利用するのが安全です。

コマンドのプレビュー確認

「!$」を使った結果、どのようなコマンドが実行されるか不安な場合は、コマンドの末尾に :p を付けることで「実行せずに表示だけする」ことができます。

Shell
# 実行内容を確認する
ls !$:p

この操作により、ヒストリには展開後のコマンドが登録されるため、上矢印キーで呼び出してそのまま実行することが可能になります。

まとめ

Bashの「!$」は、直前のコマンドの最後の引数を瞬時に呼び出すことができる、非常に強力なショートカット機能です。

「ディレクトリを作って移動する」「ファイルを確認して編集する」「コピーしたファイルの属性を変更する」といった日常的なルーチン作業において、その真価を発揮します。

さらに、:h:t といった修飾子を組み合わせることで、パスの操作も自由自在に行えるようになります。

最初は意識して使う必要がありますが、一度指が覚えてしまえば、ターミナル作業の効率は劇的に向上するでしょう。

コマンドライン操作の生産性を高める第一歩として、まずは mkdircd !$ の組み合わせから始めてみてはいかがでしょうか。

URLをコピーしました!