シェルの履歴展開入門:!! や !$ で直前のコマンドを使い回す

スポンサーリンク

シェルの履歴展開入門:!! や !$ で直前のコマンドを使い回す

bash・zsh には「履歴展開(ヒストリ展開)」という機能があります。直前のコマンドや引数を呼び出せるため、同じ文字列を打ち直す手間が省けます。

!! はビックリマーク2つ、!$ はビックリマーク+ドル記号です。「ビックリマークビックリマーク 使い方」「ビックリマーク シェル」「エクスクラメーション2つ シェル」で検索してたどり着いた方も同じものです。


よくある使い方

ls /var/log/nginx
cat !!:$
# → cat /var/log/nginx

!!:$ は「直前のコマンドの最後の引数」を意味します。ls でパスを確認して cat で中身を見る、といった操作がそのまま書けます。


!! :直前のコマンドをそのまま実行する

cat /etc/hosts
!!
# → cat /etc/hosts(同じコマンドを再実行)

権限エラーになったときに sudo を付けて再実行するのが定番の使い方です。

cat /etc/sudoers
# Permission denied

sudo !!
# → sudo cat /etc/sudoers

!$ :直前のコマンドの最後の引数

!$!!:$ の短縮形です。どちらも同じ意味です。

mkdir -p /tmp/work/logs
cd !$
# → cd /tmp/work/logs
ls hoge.txt
cat !$
# → cat hoge.txt

!^ :直前のコマンドの最初の引数

diff old.txt new.txt
cp !^ backup.txt
# → cp old.txt backup.txt

!!:n :n番目の引数

コマンド名を !!:0、1番目の引数を !!:1、2番目を !!:2 と指定します。

cp /src/file.txt /dst/file.txt
ls -l !!:2
# → ls -l /dst/file.txt
git commit -m "fix: バグ修正"
echo !!:0  # → git
echo !!:1  # → commit
echo !!:3  # → "fix: バグ修正"

!!:* :直前のコマンドの全引数

コマンド名を除いた引数すべてを取り出します。

rsync -av /src/ /dst/
ls !!:*
# → ls -av /src/ /dst/

!!:n-m :引数の範囲を指定する

echo a b c d e
echo !!:2-4
# → echo b c d

!string :string で始まる直近のコマンドを再実行する

!git
# git で始まる最後のコマンドを実行
!ssh
# ssh で始まる最後のコマンドを実行

実行前に確認したい場合は :p を付けると表示だけして実行しません。

!git:p
# git commit -m "fix: バグ修正"  ← 実行せず表示だけ

oldnew :直前のコマンドの文字列を置換して再実行する

タイポを直したいときに使います。

git chekcout main
# error: pathspec 'chekcout' did not match any file(s)

^chekcout^checkout
# → git checkout main
curl http://staging.example.com/api/users
^staging^prod
# → curl http://prod.example.com/api/users

まとめ

書き方 展開される内容
!! 直前のコマンド全体
!$ 直前のコマンドの最後の引数
!^ 直前のコマンドの最初の引数
!!:n 直前のコマンドのn番目のトークン(0=コマンド名)
!!:* 直前のコマンドの全引数(コマンド名除く)
!!:n-m 直前のコマンドのn〜m番目のトークン
!string stringで始まる直近のコマンド
!string:p 実行せず表示だけ
^old^new 直前のコマンドのoldをnewに置換して実行

使いどころ

# ls で確認したパスをそのまま cat に渡す
ls /var/log/app.log
cat !$

# Permission denied → sudo で再実行
cat /etc/sudoers
sudo !!

# タイポを修正して再実行
git psuh origin main
^psuh^push

コマンドの出力を加工するには「macでjqを使う:JSONをコマンドラインで操作する方法」も参照してください。

historyをインクリメンタルに絞り込むには「fzf入門:zshのhistory検索・ファイル検索を強化する設定」も参照してください。