DevOpsプロ級に見える10のShellコマンド:実務で差がつく使い方と活用場面

Published on: | Last updated:

最近、後輩から「先輩、なんでそんなにターミナル操作が速いんですか?」って聞かれることがあって。いや、別に魔法とかじゃないんだよ、これ。正直、知ってるか知らないか、ただそれだけの差なんだよね。

昔は僕も、なんかエラーが出たらすぐにGoogle開いて、コピペして…みたいな感じだった。でも、いくつかのコマンドとその「組み合わせ方」を覚えたら、世界が変わった。マジで。

TL;DR

要するに、面倒な作業はぜーんぶコマンドにやらせちゃおうぜって話。この記事では、僕が「これ知っててよかった…」って心から思う、ちょっとマニアックだけど超便利なコマンドたちを紹介するね。一つでも覚えて帰ってくれたら嬉しい。

コマンドをパイプで繋ぐイメージ
コマンドをパイプで繋ぐイメージ

「探す」を極める:find と grep の最強タッグ

新しいプロジェクトに入った時とか、大量のファイルの中から「あの設定、どこに書いてあったっけ…?」ってなること、あるでしょ?もう手作業でディレクトリを一つずつ開いていくなんて、時間がもったいなさすぎる。

そういう時に使うのがこれ。

find . -type f -name "*.yml" -exec grep -l "database-url" {} \;

これは何をしてるかっていうと、まず `find` で「カレントディレクトリ以下の、`.yml` で終わるファイル」を全部リストアップして、その一つ一つのファイルに対して `grep` で「`database-url` っていう文字列が含まれてるか」をチェックしてる。`-l` オプションのおかげで、中身じゃなくてファイル名だけを返してくれるのがミソ。めっちゃ便利。

いつ使うの?

  • 特定のAPIがどのファイルで使われてるか調べたい時
  • 非推奨になった古い関数を全部洗い出したい時
  • 設定ファイルがあちこちに散らばってて、一括で探したい時

先月も、ログフレームワークを更新しなきゃいけなくなった時に、50個以上あるマイクロサービスのリポジトリを一個一個開く代わりに、このコマンド一発で対象のファイルを全部特定できた。数時間かかると思ってた作業が、ほんの数十秒で終わったんだよね。

「加工する」を覚える:grep, sed, awk の使い分け

ログを見たり、コマンドの出力を整形したり。テキストを「探す」だけじゃなくて、「加工」したい場面はめちゃくちゃ多い。ここでよく出てくるのが `grep` `sed` `awk` の三兄弟。僕も昔はごっちゃになってたから、ここで整理してみようか。

この3つの使い分けができるようになると、一気に見える世界が変わるよ。

コマンド 得意なこと(一言で言うと) 僕なりの使い方コメント
grep 「この文字列、どこにある?」を探す専門家。 一番シンプル。まずはこいつ。とにかく「見つける」だけ。パイプ(`|`)で繋いで、他のコマンドの出力を絞り込む時によく使う相棒。
sed 見つけた文字列を「これに置き換えて!」が得意な編集者。 `s/old/new/g` の置換が超有名。ファイルの中身を直接書き換えられる(`-i` オプション)のが強力だけど、ちょっと危険。バックアップは忘れずにね。設定ファイルの一括更新とかで神。
awk 行を「列」で分解して処理するデータサイエンティスト。 こいつが一番手強いけど、最強。ログみたいにスペースやカンマで区切られたデータの「2列目と5列目だけ欲しい」とか「4列目の数値が500以上なら表示」みたいな、表計算ソフトみたいな処理が得意。

実例:awkでヤバいプロセスを特定する

例えば、なんかサーバーが重いな…って時。`ps` コマンドでプロセス一覧を見るけど、情報が多すぎてわからん!ってなる。

ps aux | awk '$3 > 5.0 {print $2, $3, $11}'

これは、`ps aux` の出力(プロセス一覧)を `awk` に渡して、「3列目(CPU使用率)が 5.0 より大きい行だけ」を抽出して、さらに「2列目(PID)、3列目(CPU%)、11列目(コマンド名)」だけを表示させてる。これで、CPUを食い潰してる犯人が一瞬でわかる。

実例:sedで設定ファイルを一斉に書き換える

データベースのURLを古いものから新しいものへ、200個以上のサービスで全部変更しなきゃいけない…考えただけでゾッとするよね。でも `sed` があれば大丈夫。

find . -name "config.json" -exec sed -i 's/old-db\.example\.com/new-db\.example\.com/g' {} \;

`find` で設定ファイルを見つけて、`sed` で中身を書き換える。このコンボ技。 `-i` オプションは「直接ファイルを上書きする」っていう意味だから、使う前には必ず、`-i` をつけずに実行して、意図通りに置換されるかテストするのが鉄則。マジでこれやらないと、後で泣くことになるからね。

「JSONとAPI」を制する:jqは現代の必須科目

今の時代、API叩いて返ってきたJSONを処理するなんて日常茶飯事。でも、あのぐちゃっとしたJSONを手で読むのは地獄。そこで登場するのが `jq`。

こいつはJSONをきれいに整形したり、特定のキーの値だけを抜き出したりできる、まさにJSON界の神ツール。

curl -s 'https://api.github.com/repos/<a href="https://kubernetes.io/docs/concepts/overview/what-is-kubernetes/" target="_blank" class="blogHightLight_css nobox">kubernetes</a>/kubernetes/releases/latest' | jq -r '.tag_name'

GitHubのAPIを叩いて、最新のKubernetesのリリースタグ名だけを抜き出す、みたいなことが一瞬でできる。`-r` (`--raw-output`) をつけると、ダブルクォーテーションなしのプレーンなテキストで出力してくれるから、他のコマンドにそのまま渡せて超便利。

あ、ちなみにmacOSユーザーなら、`jq` は標準で入ってないことが多い。でも心配しないで、Homebrew さえ入ってれば `brew install jq` で一発だから。Linux環境だと大体最初からあるのに、この辺がちょっと違うところだよね。まあ、`jq` も元をたどればCで書かれたポータブルなツールだから、環境依存は少ない方だけど。

tmuxで分割されたターミナル画面
tmuxで分割されたターミナル画面

「ながら作業」の決定版:tmuxでターミナルを要塞化

ターミナルのタブを何個も開いてると、どれがどれだか分かんなくならない?僕はなる。デプロイしながら、ログを監視して、別のサーバーの様子も見て…とかやってるともうパニック。

`tmux` は、そんなカオスを解決してくれる。一つのターミナルウィンドウの中で、画面を分割したり、複数の「セッション」を管理したりできるんだ。

何が最高かって、SSHでサーバーに繋いで `tmux` の中で重い処理を動かしてるときに、もし自分のPCのネットワークが切れちゃっても、サーバー上では処理が動き続けてくれること。後でまたSSHで繋ぎ直して `tmux attach` すれば、何事もなかったかのように作業を再開できる。これ、一度経験するともう `tmux` なしでは生きていけなくなるよ。

基本的なショートカット(僕がよく使うやつ)

  • `Ctrl+b` `"`: 画面を上下に分割
  • `Ctrl+b` `%`: 画面を左右に分割
  • `Ctrl+b` `矢印キー`: ペイン(分割した画面)間を移動
  • `Ctrl+b` `d`: 現在のセッションから抜ける(デタッチ)
  • `tmux attach -t [セッション名]`: デタッチしたセッションに戻る

デプロイ作業とかで、片方でデプロイコマンドを流し、もう片方で `tail -f` でログを監視、さらにもう一つで `top` コマンドを…みたいなことが1画面で完結する。見た目もハッカーっぽくてカッコいいしね(笑)。

「めんどくさい」を自動化する:SSH設定とエイリアス

毎日何回も同じサーバーにSSH接続するのに、いちいち `ssh user@xxx.yyy.zzz.www -i ~/.ssh/my_key.pem` みたいな長いコマンド打つの、正直だるいよね。

そういうのは `~/.ssh/config` ファイルに書いちゃおう。

Host prod-web
    HostName 192.0.2.10
    User myuser
    IdentityFile ~/.ssh/prod_key

Host stg-db
    HostName stg-db.example.com
    User admin
    IdentityFile ~/.ssh/stg_key
    ProxyJump bastion-server

こう書いとけば、本番のWebサーバーには `ssh prod-web`、ステージングのDBには `ssh stg-db` って打つだけで入れるようになる。`ProxyJump` を使えば、踏み台サーバー経由の接続も一発。マジで楽。

もっと簡単なレベルだと、`~/.bashrc` とか `~/.zshrc` にエイリアスを登録するのも基本だね。

# kubectlをkだけで使えるようにする
alias k="kubectl"

# docker psの結果をちょっと見やすくする関数
dps() {
    docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}" | grep "$1"
}

`k get pods` とか `dps my-container` みたいに使えるようになる。こういう小さな積み重ねが、日々のストレスをめちゃくちゃ減らしてくれるんだ。

Gitのbisectで問題のコミットを特定するイメージ
Gitのbisectで問題のコミットを特定するイメージ

「やらかし」を過去に遡る:Gitのbisectはタイムマシン

「先週までは動いてたのに、いつの間にかバグってる…どのコミットが原因だ…?」っていう絶望的な状況、経験したことある?一個一個コミットを `checkout` して動作確認…なんてやってられない。

そんな時こそ `git bisect` の出番。これは、Gitが自動でコミット履歴を二分探索して、バグが混入したコミットを特定してくれる魔法のコマンド。

使い方はこんな感じ。

  1. `git bisect start`: タイムトラベル開始の合図。
  2. `git bisect bad`: 「今の最新のコミットはバグってるよ」と教える。
  3. `git bisect good [正常だった頃のコミットIDやタグ]`: 「この時点では正常だったよ」と教える。
  4. あとはGitが自動で中間のコミットをチェックアウトしてくるので、動作確認して `git bisect good` か `git bisect bad` を繰り返すだけ。

テストを自動化できるなら、`git bisect run ./test-script.sh`みたいにすれば、全自動で犯人を見つけてくれる。手動でやったら半日かかる調査が、数分で終わることもある。これはもう、知ってるか知らないかで人生が変わるレベル。

まとめというか、最後に

今回紹介したコマンドって、別に特別なものじゃない。でも、これらを「どういう時に」「どう組み合わせて」使うか、その引き出しの数が、作業効率を大きく左右するんだと思う。

いきなり全部を使いこなすのは無理だから、まずは「あ、この作業、もしかして `awk` 使ったら楽になるんじゃね?」みたいに、一つでもいいから試してみてほしい。その小さな一歩が、たぶん一番大事。

この中で、明日からすぐ使ってみたいって思ったコマンド、あった?もし良かったらコメントで教えてよ。みんなが使ってる意外な組み合わせ技とかも知りたいな!

Related to this topic:

Comments