世界を動かす技術を、日本語で。

生活を楽にするシェルの裏技(心の平穏も守る)

概要

  • 優れたエンジニアでも、非効率なターミナル操作に陥りがち
  • POSIX互換シェルで使える便利なショートカットやコマンドを紹介
  • Bash/Zsh限定の快適機能も網羅
  • 作業効率を劇的に向上させるテクニック集
  • 日常的に一つずつ習得することを推奨

ターミナル操作の非効率とその解決策

  • エンジニア でも、行頭のタイプミス修正時に Backspace長押し をしがち
  • ls, cd, grep など基本コマンドを覚えた後、効率化を怠る傾向
  • ターミナルは「住まい」だが、 家具の配置換え (効率化)をしない現状

ほぼ全てのPOSIX系シェルで使える基本テクニック

  • Emacs風ショートカット (Readline対応シェルで標準)
    • CTRL + W :カーソル直前の単語を即削除
    • CTRL + U/K :行頭/行末まで一気にカット、 CTRL + Y で再貼り付け
    • CTRL + A/E :行頭/行末に瞬間移動
    • ALT + B/F :単語単位で前後移動(MacはOptionキー設定要)
  • reset (または stty sane):バイナリファイルcat後のターミナル復旧
  • CTRL + C :コマンド即中断
  • CTRL + D :EOF送信、空行でシェル終了に注意
  • CTRL + L :画面クリア、入力中コマンドはそのまま
  • cd - :直前のディレクトリに即戻り
  • pushd/popd :複数ディレクトリのスタック管理
  • > file.txt :ファイル内容を即空に、パーミッション等維持
  • $_ :直前コマンドの最終引数展開、パス再利用に便利
  • set -e/-u :スクリプトのエラー時即終了、未定義変数利用時エラー

Bash/Zsh限定の快適ショートカット集

  • CTRL + R :履歴から逆検索、キーワード入力で過去コマンドを即呼び出し
  • !! :直前コマンド全文展開、sudo !!で「権限昇格リトライ」
  • CTRL + X, CTRL + E :現在のコマンドラインをエディタで編集&即実行
  • fc :$EDITORで直前コマンドを編集、BashやZsh以外でも利用可
  • ESC + .(ALT + .) :直前コマンドの最後の引数を挿入、連打でさらに遡れる
  • !$ :直前コマンドの最後の引数を即展開(入力時編集不可)
  • 中括弧展開(brace expansion)
    • cp pf.conf{,.bak} :バックアップファイルの一発作成
    • mv filename.{txt,md} :拡張子変更を一瞬で
    • mkdir -p project/{src,tests,docs} :複数ディレクトリ同時作成
  • プロセス置換(process substitution)
    • diff <(sort file1.txt) <(sort file2.txt) :一時ファイル不要の比較
  • グロブスター(globstar)
    • shopt -s globstar で **ls ** /*.js:再帰的なファイル検索が簡単に
  • バックグラウンド&切り離し
    • CTRL + Z で一時停止、 bg でバックグラウンド化、 disown でターミナルから切り離し
  • |& tee file.log
    • 標準出力・標準エラー出力を同時に画面表示&ログ保存

ターミナル習熟のすすめ

  • シェルは 障害物競走 ではなく 道具箱
  • 全てを一度に覚える必要なし、 一つずつ習得 して習慣化
  • ターミナルの「家具」を 自分好みに配置 して快適作業環境の構築

Hackerたちの意見

LLMっぽい見出しはあんまり好きじゃないし、アドバイスもバラバラな感じだね(シェルじゃなくてreadlineライブラリにちゃんとクレジットをあげてほしいところもあるけど)。でも、ここには試してみたいことがいくつかあるよ。ブレース展開が嫌いな理由の一つは、タブ補完と上手く連携しないこと。例えば、最後のトークンを簡単に複製したり(エスケープされたスペースや引用符付きのスペースも含めて)、ファイル名のサフィックスを削除したりするのが楽だといいな。それと、変数や~をすぐに展開してほしい(エンターを押した後じゃなくて)。

readlineの話だけど、最近PowerShellにreadlineモードがあることを知ったよ。めっちゃ便利だね。WSLで主に作業してて、たまにPSを使うから、コンテキストスイッチの手間がかなり減る。

CTRL + Wは通常、前の空白までの全てを削除するから、OPの例だと'/var/log/nginx/'の文字列が全部消えちゃうよ。Alt + バックスペースは通常、非英数字の文字に出会うまで削除するんだ。ただ、CTRL + Wを筋肉記憶に組み込むのは気をつけてね、ブラウザのタブを何回閉じたか数えきれないよ…

Ctrl-Shift-Tを押すと、少なくともそのタブがすぐ戻ってくるよ。

私のターミナルでは全く逆で、Alt-Backspaceは前のスペースまで削除するけど、Ctrl-Wは最後の非英数字(例えば/)まで削除するんだ。Alacrittyターミナルでfishシェルを使ってるよ。うん、時々Ctrl-Wを誤って押しちゃうのは面倒だけど、FirefoxのCtrl-Shift-Tは神だね。

CTRL + Wを筋肉記憶にするのは気をつけてね、ブラウザのタブを何回閉じたか数えきれないよ…これ痛い。あと、シェルではC+wをやると、C+yで「貼り付け」できるよ。設定を消してなければだけど。

$WORDCHARSをそれに合わせて設定してね。君の場合、$WORDCHARSから/を削除するといいよ。https://unix.stackexchange.com/a/726014

ctrl+rを2回押すと、最後に検索した内容で自動補填されるよ。もっと押すと履歴を遡ることができる。最近、Dockerの作業をしているときによく使ってる。ctrl+rでコンテナ名を入力して、compose buildコマンドが出るまで続ける。ctrl+r、ctrl+r、ログコマンドが出るまで繰り返す。そうすれば、ビルドとログコマンドを簡単に取得できる。ctrl+rは友達だね。ctrl+r

fzfとシェル統合を追加すると、Ctrl+rがもっと便利になるよ!

この記事のコメントから好きな部分があるんだけど:彼はパスに#というスクリプトを持っていて、mycmd1 | # mycmd2 | mycmd3みたいにパイプ要素をコメントアウトするのに使ってたんだ。このスクリプトはこう書かれてた:#!/bin/sh cat

うん!これ、$PATHに入れるわ。catの使い方としてはめっちゃ便利だね!

似たようなトリック: #!/bin/sh $* これが俺の~/bin/noglobファイルなんだけど、bashからnoglobを使うzshスクリプトを呼ぶときに、壊れないようになってるんだ。

mycmd1 #| mycmd2 で何が得られるの?

cd -: クラシックなチャンネル切り替え。行ったり来たりするのにぴったり。cdだけじゃなくて、'git checkout -'も好きだな。

'-'のショートカットは変だね。'git commit -F -'では、'-'は実際には/dev/stdinなんだ。

vimモードを有効にすると、ターミナルがすごく快適になるよ。3語前にミスした?問題なし、3bcwで大丈夫。全部削除したい?もっと簡単、ccだし、複雑なリワークのために完全な(neo)vimインスタンスでコマンドを開くこともできる。すでに(neo)vimを使っているなら、新しいショートカットを覚える必要がないから、これが一番いい方法だよ。

おお、これ知らなかった、ありがとう!この機能は「readline vi-mode」って呼ばれてるから、もっと知りたい人は調べてみて。

もう20年以上(n)vim使ってるけど、シェルのviモードは嫌いなんだよね。でも、複雑なコマンドを実行する必要があると感じたら、ctrl-x+eでneovimを開くようにしてる(EDITOR=nvimを設定してるから)。これがちょうどいい妥協点だと思ってる。

3bcw あなたのキーボードレイアウトは何?これ、普通のqwertyキーボードに対する人類への犯罪に見えるんだけど。

これ、古いEmacsマニュアルの一節を思い出させるなぁ: . . . ウィンドウに関するコマンドを忘れたら、@b[ESC-?]@t[window]@b[ESC]って入力してみて。こんな変なコマンドが、まるで世界で一番簡単なことのように無邪気に紹介されてる。コマンドライン編集のためには、マウスを設定する方がいいアドバイスだと思う。

cc 挿入モードでcontrol+oを押すと、一時的に通常モードに切り替わって、1つの通常モードのコマンドを実行できる。その後、また挿入モードに戻れるから、再度'i'を押す必要はないよ。だから、'cc'の代わりに'S'を使うといい。

複雑なコマンドを実行したり修正したりする時に、vは本当に助けられることが多い!

いつも使ってる裏技:長いコマンドを打ってるとき、実行する前にやることを思い出すことがあるよね。その時、Ctrl-Cでキャンセルする代わりに、無効な形で履歴に残すんだ。行の先頭に#を付けてコメントにして、コメントした行を実行して履歴に追加。思い出したことをやってから、上矢印で最初のコマンドを取り出す。$ long_command $ #long_command $ stuff_1 $ stuff_2 $ #long_command $ long_command

ちなみに、Bashではalt-shift-3を押すと、現在のコマンドの先頭に#を付けて新しいコマンドを始めるよ。

zshでは「push-line-or-edit」をバインドできるよ。bashやすべてのreadlineプログラムでは、C-uの後にC-y(つまりカット&ペースト)で近いことができる。ただ、俺の履歴はまだ'#'や':'(cshのトラウマ)がついたコマンドラインでいっぱいだけどね…

履歴について: ZSHの設定に、特定のものを履歴から除外する関数を入れてる。特に、CTRL-Rで間違ったものを呼び出したときに壊れちゃうようなものね。こんな感じ: # 特定の文字列を履歴に表示しないようにする # 先頭にスペースがあるものは無視 # "--force"や"whatever"を含むものは無視する function zshaddhistory() { emulate -L zsh if ! [[ "$1" =~ "(^ |--force|whatever)" ]] ; then print -sr -- "${1%%$'\n'}" fc -p else return 1 fi }

いろんなキーの組み合わせを使ってきたけど、この2つは知らなかったな。これ、コンソール操作にめっちゃ便利な追加機能だと思う!教えてくれてありがとう。22年使ってるけど、これには気づかなかったよ :D CTRL + U と CTRL + K CTRL + W このキーの組み合わせが好きなのは、ほとんどどのプログラムでも使えるってこと。LinuxやMacの多くのプログラムがこれらの組み合わせをそのままサポートしてるから、生産性が一気に変わるよね。特に行の先頭や末尾にジャンプしたり、単語ごとに前後に移動するのが、キーボードだけで作業するのをすごく快適にしてくれる。エディタでAVYを使えば、さらに素早く移動できるし。

俺が人生が変わったと思うのは、上矢印キーを再マッピングして、すべてのコマンドを順番に表示するんじゃなくて、すでに入力した文字で始まるコマンドだけを表示するようにしたこと。例えば、tar -って入力してから上矢印を押すと、前回使ったtarのパラメータが出てくるんだ。zshでは、これを以下のように設定できるよ。 bindkey "^[OA" up-line-or-beginning-search # 上 bindkey "^[OB" down-line-or-beginning-search # 下

人生が変わる さらに人生が変わる体験をしたいなら… .bash_aliasesにエイリアスを追加してみて。 alias gph='history | grep --colour -i ' alias gpc='grep --colour -Hin '

GNU timeがインストールされている場合

alias timef='/usr/bin/time -f "tm %E , cpu %P , mem %M" '

CTRL+rを使い始めたら、もう上矢印を使うことはないかもしれないよ。

何年も前に(でもbashで)やったけど、人生が変わったって表現は的を射てるね。