まずはこのステップを実行してみて - findとgrepで新しいプロジェクト迷子を秒速解決する即効テクニック
- findコマンドで3分以内に更新されたファイルだけ一覧化
直近編集した場所へ一発ジャンプ、無駄な捜索ゼロ
- grep -rn `TODO` . | head -10で埋もれた作業メモを抽出
最重要タスクや注意点を10秒で拾い上げ迷走防止
- -name `*.sh`など拡張子フィルター併用し対象範囲を30%以下に限定
`全部検索`から卒業、不要なノイズ激減
- -execオプション使いヒットファイル5件のみcat表示
中身の瞬間確認が可能、開く手間ごと消せる
新しいプロジェクトで迷子、findとgrepの不思議な旅
# 10個のShellコマンドで、DevOpsのプロみたいに見えるかもしれない話
**Mediumの会員じゃなくても、ここから全文読めるらしい。ふーん。**
「えっ、何入力してるの? なんでそんなに指が速いんだ……。」気付いたらシニアDevOpsエンジニアがターミナルに向かっていて、必要な情報が次々出てくる。ああ、自分はというと、コマンド名すら怪しくてGoogle先生に毎回頼りっぱなしだった。あの瞬間、「もう少しゆっくりやってくれませんか?」とお願いした自分がいる。うーん、3年前のことだけどさ。
いや、本当にその時は焦った。「自分何もできてないじゃん…」ってちょっと落ち込んだ。でも、コマンドライン操作って別世界の技術でも魔法でもなくて――練習さえすればちゃんと体に染み込むものなんだな、と後になって思うようになった。
ま、それはさておき。本当は今でも「自分遅いな」と思う瞬間もあるけど、不思議と最近「どうしてそんな早いんですか?」とか後輩エンジニアから聞かれることも増えてきた。不思議なものだね。そこで、自分自身が「ターミナル遅い人」からいつの間にか質問される側になるまで――役立った10個のshellコマンドとテクニックをこっそり紹介してみる。
## 1. `find` + `grep`でファイル探し迷子から解放
新しいプロジェクト入った時、大量ファイルを前に「あれ…目的のファイルどこ?」状態になったこと、一度くらいあるよね? 昔、自分はひたすらディレクトリ一個ずつ目視で漁ってて、午後全部潰した日もあった。本当に無駄だった…。ところが同僚に教わったこのコマンド連携使ったら、その作業時間ごっそり減ったんだよな。えっと、それだけなんだけど。また話逸れた気もするけど、本題戻ろうか。
**Mediumの会員じゃなくても、ここから全文読めるらしい。ふーん。**
「えっ、何入力してるの? なんでそんなに指が速いんだ……。」気付いたらシニアDevOpsエンジニアがターミナルに向かっていて、必要な情報が次々出てくる。ああ、自分はというと、コマンド名すら怪しくてGoogle先生に毎回頼りっぱなしだった。あの瞬間、「もう少しゆっくりやってくれませんか?」とお願いした自分がいる。うーん、3年前のことだけどさ。
いや、本当にその時は焦った。「自分何もできてないじゃん…」ってちょっと落ち込んだ。でも、コマンドライン操作って別世界の技術でも魔法でもなくて――練習さえすればちゃんと体に染み込むものなんだな、と後になって思うようになった。
ま、それはさておき。本当は今でも「自分遅いな」と思う瞬間もあるけど、不思議と最近「どうしてそんな早いんですか?」とか後輩エンジニアから聞かれることも増えてきた。不思議なものだね。そこで、自分自身が「ターミナル遅い人」からいつの間にか質問される側になるまで――役立った10個のshellコマンドとテクニックをこっそり紹介してみる。
## 1. `find` + `grep`でファイル探し迷子から解放
新しいプロジェクト入った時、大量ファイルを前に「あれ…目的のファイルどこ?」状態になったこと、一度くらいあるよね? 昔、自分はひたすらディレクトリ一個ずつ目視で漁ってて、午後全部潰した日もあった。本当に無駄だった…。ところが同僚に教わったこのコマンド連携使ったら、その作業時間ごっそり減ったんだよな。えっと、それだけなんだけど。また話逸れた気もするけど、本題戻ろうか。
awk怖い?データ整形で見える世界が変わった日々
findコマンドの話、またか、って自分でも思うけどさ。まあ、疲れてる時に限って「あれ?DatabaseConnectionってどこで定義してたっけ」みたいなことになるんだよね。えっと、とにかく、このコマンドなんだけど——
こんな感じで書くと、今いるディレクトリ以下(そう、サブディレクトリも全部ね)に存在するすべてのJavaファイルから「DatabaseConnection」という文字列を探して、一致したファイル名だけを列挙してくれる。実は昔この説明を書いた時、「grep -rとかでも良いんじゃない?」と思ったけど…いや、それだと余計な内容まで出力されてしまうし、ごちゃごちゃになるんだよね。ああ、話逸れた。でもやっぱりこれが一番手軽。
さて、と。具体的な例を書くと、先月だったかな、50個以上あるマイクロサービスを相手にロギングフレームワークのアップデートしろ!みたいなお達しが出てさ…。各プロジェクトを一個ずつ開いてられるほど余裕なくて、このコマンド使ったんだよ。
これだけでlog4j使ってるMavenプロジェクト全部洗い出せたし、そのままVS Codeで一気に開けた。本当に助かった…。作業時間?大幅短縮だったよ。うーん、もう少し早く知りたかったな。
あと、小技というかプロチップ的なのだけど、大文字小文字区別せず検索したい時はgrepに-i付ければいい。それだけなんだけどね。「ま、とりあえず覚えておけば損はない。」
## 2. `awk`によるデータ操作
awkって聞くだけで難しいイメージ持つ人、多いよね。正直、自分も前までは「あー無理」って逃げてた。でも最近は不思議と使う機会が増えた気がする。いや、本当になぜだろう…。
これね、一見ぱっと見ただの数字並びそうだけど――メモリ利用率5%以上のプロセスについてPID・メモリ使用率・コマンド名のみ表示してくれる。「ふーん」で流すには惜しい便利さというか。
この前起きた障害対応――ほんと眠気との戦いだったんだけど。APIサーバーがやたらメモリ食ってて、「何だコレ」と思ったものの結局原因特定できなくて詰んでた。でもふと思いついてawk+ログ解析試したら意外とうまく行った。
この連携プレイ(?)によってログからAPIエンドポイント部分だけ抜き出せるわけ。そしてアクセス回数順トップ10まで一覧可能。一部クライアントによる特定エンドポイントへの過剰アクセス傾向も発覚した。「いや~偶然じゃない?」とか思ったけど事実だったっぽい。しかし…疲労困憊の日々は続くのであった。
find . -type f -name "*.java" -exec grep -l "DatabaseConnection" {} \;
こんな感じで書くと、今いるディレクトリ以下(そう、サブディレクトリも全部ね)に存在するすべてのJavaファイルから「DatabaseConnection」という文字列を探して、一致したファイル名だけを列挙してくれる。実は昔この説明を書いた時、「grep -rとかでも良いんじゃない?」と思ったけど…いや、それだと余計な内容まで出力されてしまうし、ごちゃごちゃになるんだよね。ああ、話逸れた。でもやっぱりこれが一番手軽。
**使用タイミング:**
- ある関数やクラスがプロジェクトのどこで定義・使用されてるかちょっと調べたい瞬間。
- 非推奨API(deprecated API)がまだ残ってないか探したい場合にも便利。
- それから…設定値とかが複数ファイルに分散してる時も役立つ、意外とこういう場面多い。(あれ、この前も同じこと考えてた気がする…)
さて、と。具体的な例を書くと、先月だったかな、50個以上あるマイクロサービスを相手にロギングフレームワークのアップデートしろ!みたいなお達しが出てさ…。各プロジェクトを一個ずつ開いてられるほど余裕なくて、このコマンド使ったんだよ。
find . -type f -name "pom.xml" -exec grep -l "log4j" {} \; | xargs code
これだけでlog4j使ってるMavenプロジェクト全部洗い出せたし、そのままVS Codeで一気に開けた。本当に助かった…。作業時間?大幅短縮だったよ。うーん、もう少し早く知りたかったな。
あと、小技というかプロチップ的なのだけど、大文字小文字区別せず検索したい時はgrepに-i付ければいい。それだけなんだけどね。「ま、とりあえず覚えておけば損はない。」
## 2. `awk`によるデータ操作
awkって聞くだけで難しいイメージ持つ人、多いよね。正直、自分も前までは「あー無理」って逃げてた。でも最近は不思議と使う機会が増えた気がする。いや、本当になぜだろう…。
**コマンド:**
ps aux | awk '$4 > 5.0 {print $2, $4, $11}'
これね、一見ぱっと見ただの数字並びそうだけど――メモリ利用率5%以上のプロセスについてPID・メモリ使用率・コマンド名のみ表示してくれる。「ふーん」で流すには惜しい便利さというか。
**使用タイミング:**
- コマンド出力から必要なカラムだけ抜き取りたい
- データ上で簡単な計算処理をその場で済ませちゃいたい
- レポート向けとかでテキスト整形したい局面にも意外と重宝する(実際何回も助かった記憶…)
この前起きた障害対応――ほんと眠気との戦いだったんだけど。APIサーバーがやたらメモリ食ってて、「何だコレ」と思ったものの結局原因特定できなくて詰んでた。でもふと思いついてawk+ログ解析試したら意外とうまく行った。
cat access.log | awk -F'"' '{print $2}' | awk '{print $2}' | sort | uniq -c | sort -nr | head -10
この連携プレイ(?)によってログからAPIエンドポイント部分だけ抜き出せるわけ。そしてアクセス回数順トップ10まで一覧可能。一部クライアントによる特定エンドポイントへの過剰アクセス傾向も発覚した。「いや~偶然じゃない?」とか思ったけど事実だったっぽい。しかし…疲労困憊の日々は続くのであった。

sed触るだけで数百ファイルを瞬時に書き換えた話
【プロのヒント】:あ、そういえばさ、`-F` フラグってフィールドセパレータを変えるためのものなんだよね。えっと、CSVとかカスタムログフォーマットいじる時は本当に重宝するやつ。まあ、知ってて損はないかも。
## 3. `sed`で手軽にテキストを変換
なんか「sedって難しそう」と思われがちだけど…実際には意外と簡単という人もいる。不思議なことに最初は避けてたくせに、「今では毎日のように使ってる」みたいな話もちょこちょこ耳にするんだよなあ。
この方法なら全体のマイクロサービス群、それぞれの設定内DB接続文字列について一括検索&更新できちゃったわけです。一部じゃ「何日もかかったらどうしよう」みたいな雰囲気だったらしいけど……意外と短時間、その日のうちに終わったとも聞いたことあるし、本当助かったぽいね。
**プロからの提案:**
ま、一応注意点としてさ……`sed` コマンドはいきなり `-i` フラグ付けずドライランして変更箇所ちゃんと確認した方が後悔少ないと思う。失敗すると地味につらいから。(まあ、自分にも覚えあるけど。)
## 3. `sed`で手軽にテキストを変換
なんか「sedって難しそう」と思われがちだけど…実際には意外と簡単という人もいる。不思議なことに最初は避けてたくせに、「今では毎日のように使ってる」みたいな話もちょこちょこ耳にするんだよなあ。
**コマンド例:**
sed -i 's/old-api-url\.com/new-api-url\.com/g' config/*.json
このコマンド一発でconfigディレクトリ配下全部のJSONファイルが "old-api-url.com" から "new-api-url.com" に置き換わっちゃう。ま、いいか。…いや、それだけじゃなくて細かいところ気になる人もいるかな。でも基本はこれで十分。
**使用シーン:**
- 設定ファイルまとめて書き換え
- データクリーニング的な作業にも
- テキストパターンの削除や修正にも便利だったりして
うーん、ときどき「実際どうなの?」と疑問湧くけど…。
**実際の事例:**
ある現場(名前忘れたけど)で200以上サービスが新しいデータベースクラスターへ移動させられる羽目になったことがあったんだ。それぞれ設定ファイル個別対応?めんどくさいよね…。でもここで救世主登場、という感じで次みたいな `sed` コマンド使われた。bash
find . -name "application.properties" -exec sed -i 's/jdbc:mysql:\/\/old-db:3306/jdbc:mysql:\/\/new-db-cluster:3306/g' {} \;
この方法なら全体のマイクロサービス群、それぞれの設定内DB接続文字列について一括検索&更新できちゃったわけです。一部じゃ「何日もかかったらどうしよう」みたいな雰囲気だったらしいけど……意外と短時間、その日のうちに終わったとも聞いたことあるし、本当助かったぽいね。
**プロからの提案:**
ま、一応注意点としてさ……`sed` コマンドはいきなり `-i` フラグ付けずドライランして変更箇所ちゃんと確認した方が後悔少ないと思う。失敗すると地味につらいから。(まあ、自分にも覚えあるけど。)
jq×AWS監査:JSON地獄から救われる日もある
## 4. `jq`でJSONを効率的に解析
APIとか、JSONデータの操作って、まあ日々のDevOps作業にはもう切り離せない。えっと、`jq`を覚えるとね、思った以上に作業がラクになることもあるんだよな。たぶん、それを知らずに手動でやってる人も多いかもしれないけど…。うーん、自分も最初は「本当に必要?」とか疑問だった。でも結局使っちゃうわけ。
現実的な話になると――例えばさ、本当にあったことなんだけど――Lambda関数が300以上あって、それらが一体どこのAWSリージョンに配置されているか監査しろと言われて…。正直めまいしたよ、最初。「全部手でやる?」みたいな絶望感。でもまあ、ここでも`jq`のお世話になったわけだ。
これ一発で関数名とリージョン一覧できちゃうというね。しかも表形式。いやほんと、「地味に神」みたいな感覚すらある。このおかげでセキュリティチームへの監査レポート提出もサクッと終わったので救われた気分だった。しかし…次はもっと大変な依頼来そうだから油断できないけど。
**補足情報:**
ちなみに`-r`フラグ使うことで、生文字列(クォートなし)として吐き出せる。それゆえ他コマンドとの連携にも困らなくなるわけ。不思議だよね、この小さい違いなのに便利さ全然違うって。
## 5. `tmux`による複数ターミナルセッション管理
昔はウィンドウ何個も開いてゴチャゴチャしてた記憶がまだ新しい…。ああ面倒だった。でも今ではどうかというと、一つの画面内ですべて整理整頓できちゃうようになったから不思議だ。本筋戻すけど、本当に導入して損はないと思う。ただ疲れてくるとなぜかウィンドウ増やしすぎて迷子になることあるんだよね……ま、いいか。
APIとか、JSONデータの操作って、まあ日々のDevOps作業にはもう切り離せない。えっと、`jq`を覚えるとね、思った以上に作業がラクになることもあるんだよな。たぶん、それを知らずに手動でやってる人も多いかもしれないけど…。うーん、自分も最初は「本当に必要?」とか疑問だった。でも結局使っちゃうわけ。
**コマンド例:**
curl -s https://api.github.com/repos/kubernetes/kubernetes/releases | jq '.[0].tag_name'
このコマンドさ…Kubernetesの最新リリース情報だけ引っ張り出して、その中からタグ名だけ抽出するって感じ。いやー、一見すると地味だけど、こういうピンポイント抽出が意外と助かるんだよな。でもちょっと話逸れるけど、自分は最初API叩くの苦手だったし…それでも今は慣れたかな、と。
**利用シーン:**
- APIレスポンスの処理時
- JSON設定から特定フィールドの抽出時
- JSONデータ形式の変換時
現実的な話になると――例えばさ、本当にあったことなんだけど――Lambda関数が300以上あって、それらが一体どこのAWSリージョンに配置されているか監査しろと言われて…。正直めまいしたよ、最初。「全部手でやる?」みたいな絶望感。でもまあ、ここでも`jq`のお世話になったわけだ。
aws lambda list-functions | jq -r '.Functions[] | [.FunctionName, .FunctionArn] | @tsv' | awk -F: '{print $1, $4}' | sort | column -t
これ一発で関数名とリージョン一覧できちゃうというね。しかも表形式。いやほんと、「地味に神」みたいな感覚すらある。このおかげでセキュリティチームへの監査レポート提出もサクッと終わったので救われた気分だった。しかし…次はもっと大変な依頼来そうだから油断できないけど。
**補足情報:**
ちなみに`-r`フラグ使うことで、生文字列(クォートなし)として吐き出せる。それゆえ他コマンドとの連携にも困らなくなるわけ。不思議だよね、この小さい違いなのに便利さ全然違うって。
## 5. `tmux`による複数ターミナルセッション管理
昔はウィンドウ何個も開いてゴチャゴチャしてた記憶がまだ新しい…。ああ面倒だった。でも今ではどうかというと、一つの画面内ですべて整理整頓できちゃうようになったから不思議だ。本筋戻すけど、本当に導入して損はないと思う。ただ疲れてくるとなぜかウィンドウ増やしすぎて迷子になることあるんだよね……ま、いいか。

tmuxの複雑な画面、分割と復帰とVPN切断事件簿
tmux new -s deploy
うーん、このコマンドは一見シンプルだけど、実際には「deploy」って名前で新しいtmuxセッションを立ち上げる話なんだよね。まあ、ペインとかウィンドウとか、色々持てる…と説明しながら、そういえば前に間違えて別の名前で作っちゃったことあったな。あれ、本当にややこしかった。でも本筋に戻すと、とりあえずこれひとつで複数作業がまとめられる仕掛けってわけ。
VPN接続が不意打ちみたいに切断された瞬間にも、不思議とプロセス自体は何事もなく継続されていた――という事例があるらしい。本当に助かった。ただ、そのあと再度接続してまたtmuxセッションへアタッチし直す手順は正直めんどくさいと思いつつ(でも楽しい部分も?)、それでも作業継続できた感触は捨て難い。「こういう運用記録してほしい」って頼まれたケースもちょっと聞いたことある。
# マウスモード有効化
set -g mouse on
## 6. コマンド連鎖とパイプライン(|)
パイプライン演算子――要するに「|」なんだけど、“何その簡単な話?”と思いつつ意外と応用範囲広いので侮れないんだよね。本当にLEGOみたいな感じで、小さなコマンド組み合わせて巨大構造物作れるって言われる所以、実感としてわかる気がする。でもまあ、人によっては苦手意識持つ人いるとか聞いたことあるし、自分もちょっと途中で飽きちゃう日もある。本題戻すと、とりあえずこの柔軟性は唯一無二じゃないかな。
うーん、このコマンドは一見シンプルだけど、実際には「deploy」って名前で新しいtmuxセッションを立ち上げる話なんだよね。まあ、ペインとかウィンドウとか、色々持てる…と説明しながら、そういえば前に間違えて別の名前で作っちゃったことあったな。あれ、本当にややこしかった。でも本筋に戻すと、とりあえずこれひとつで複数作業がまとめられる仕掛けってわけ。
**基本的な`tmux`ショートカット:**
- `Ctrl+b "` - 水平分割する時のアクションだね
- `Ctrl+b %` - これは垂直分割用(たぶん間違える人多い)
- `Ctrl+b 矢印キー` - ペイン移動。これ地味に使いやすい。
- `Ctrl+b d` - あ、デタッチ。つまり一旦離れても中身は生きてる感じになるやつ。
- `tmux attach -t deploy` - もう一回戻りたいならこれだけど…たまにタイプミスしてイラッとする。
**使用する場面:**
- 複数サーバーを同時監視したい場合とか?いや、本当によくある…。
- 長時間処理を走らせておきたい時(接続切れてもプロセス死なないように)。これ地味に助かるんだよね。
- タスクを一窓で整理したい日に限って集中できなくなる。でもtmuxなら何とかなる気がしてしまう。
**実際の利用例:**
この前、大規模本番環境デプロイでさ…APIもDBもフロントも全部同時進行だったから6個以上ターミナル開く羽目になりかけたけど、「いや、それ無理」と気付き、一つのtmuxセッションで管理したことがある。ま、その日の自分GJだったかもしれない。
- DBマイグレーション用ペイン1
- APIサーバーデプロイ用ペイン1
- フロントエンドデプロイ用ペイン1
- ログ専用に分割した表示ペイン1
- メトリクス観察専用のリアルタイム表示ペイン1
まあ、途中で「どっちがどっち?」って混乱しそうになったけど…何となく乗り越えた。
VPN接続が不意打ちみたいに切断された瞬間にも、不思議とプロセス自体は何事もなく継続されていた――という事例があるらしい。本当に助かった。ただ、そのあと再度接続してまたtmuxセッションへアタッチし直す手順は正直めんどくさいと思いつつ(でも楽しい部分も?)、それでも作業継続できた感触は捨て難い。「こういう運用記録してほしい」って頼まれたケースもちょっと聞いたことある。
**プロチップ:** `.tmux.conf`という設定ファイルを使えば細かい調整可能なんだけど…。例えばプレフィックスキーを `Ctrl+a` に換えたり、マウス対応化したり出来る。この辺、最初面倒臭そうだけど慣れると楽しい罠。
# プレフィックスキー 'C-b' から 'C-a' へ変更
unbind C-b
set-option -g prefix C-a
bind-key C-a send-prefix
# マウスモード有効化
set -g mouse on
## 6. コマンド連鎖とパイプライン(|)
パイプライン演算子――要するに「|」なんだけど、“何その簡単な話?”と思いつつ意外と応用範囲広いので侮れないんだよね。本当にLEGOみたいな感じで、小さなコマンド組み合わせて巨大構造物作れるって言われる所以、実感としてわかる気がする。でもまあ、人によっては苦手意識持つ人いるとか聞いたことあるし、自分もちょっと途中で飽きちゃう日もある。本題戻すと、とりあえずこの柔軟性は唯一無二じゃないかな。
パイプ繋げて何でもできちゃう魔法(時々失敗)
ps aux | grep java | grep -v grep | awk '{print $2}' | xargs kill -9
えっと、このコマンド、正直な話…なんでこんな面倒なのって思う瞬間あるよね。全部のJavaプロセスをずらっと探し出して、しかも「grep」自身は除外する必要があるわけで、その辺りちょっとした矛盾感じたりするんだけど、まあ実際そうでもないか…。とにかく、抽出されたPIDだけを一気にkill -9で強制終了させるという流れになる。ああ、「kill -9」って本当に容赦なくプロセス潰すから少し緊張する。でも、現場ではこういう一括操作が意外とありがたい時もあるから不思議だ。</code></pre>
**使う場面:**
複数コマンド組み合わせてごちゃごちゃしたことやりたくなる場合―例えばシステム管理や保守作業でね―よく登場する。フィルタリングとか出力変換のタイミングにも便利。ま、一歩踏み込んだワンライナー自動化とかにも役立つし。今ふと思ったけど、人間って複雑な工程ほど妙な達成感覚えるよね…そんなことないかな?いや、とにかくこういう時に活躍します。
**実例:**
昔々(いや去年か)、デプロイスクリプトの不具合でTomcatサーバーがアイドル状態のままずるずる増えていった事件があった。その都度手動で探してkillしてたらキリないから、うーん…どうしようと悩んだ結果、このパイプライン生まれた訳です。
<pre><code class="language-bash">ps aux | grep tomcat | grep -v grep | grep -v active | awk '{if ($10 > "3:00") print $2

tail -fでログ追跡、grep重ねてエラーを炙り出す夜
## 8. SSH Configと鍵を活用した安全なマルチサーバ管理
うーん、SSHの設定をちゃんと覚えたのって、そんなに昔じゃないんだよね。前は本当に、接続するたびに「あれ、このIPどこだっけ?」とか言いながら調べ直しててさ。ま、それが普通だと思い込んでた時期もあったけど…。
でも実際には`~/.ssh/config`ファイルを使えば、本当にいろんなことが楽になる。いや、正確には「楽」というより、「やっとまともになった」感じかも。
**セットアップ方法:**
例えばこんなふうに書く。
Host staging
HostName staging.example.com
User deployer
IdentityFile ~/.ssh/staging_key
みたいに短縮名だけで済むわけ。ユーザー名とかホスト名とか…何度打ち間違えたか思い出したくもない。
そうそう、現場でもこういうパターン多かった。「prod-api-1」とか「stg-db-1」みたいな命名ルールが決まってて、一回把握すればもう脳死で「ssh prod-api-1」って打てるし、細かい情報は全部隠蔽できるしね。でも新メンバーが混乱せず即戦力化できるようになった事例、多分そこまで珍しくない気もする。逆に言えば、この仕組みなしだと泥沼だったとも言える。
…ところでProxyJump知ってる?バスティオン経由の場合だけど、自分最初意味不明だった(ぼーっとしてて)。でもconfig内にこう書けばいい:
なんというか、一度慣れるともう戻れない感じ?
## 9. シェル関数・エイリアスによる反復作業自動化
同じ長ったらしいコマンドばっかり毎日手入力してた頃――いや本当に指つりそうだったんだけど、その反省からエイリアスや関数を覚え始めた記憶がある。まあ、人間は学ぶ生き物だからね…。
Kubernetes運用では特に痛感したけど、とにかく繰り返し同じ文字列ばっかり打つ羽目になるので、次第に関数量産機になった自分…。ま、それでも効率上げられて救われた側面は否定できないかな。
Pod一覧取得とかログ追跡とかexec操作用にも色々作った:
こういうショートカットのお陰で「kl api-server」と叩くだけですぐAPIサーバPodからログ流せたり、「ke database-pod mysql」でMySQLシェル入れたり、とても助かった瞬間多かった。うーん…単純化すると地味なんだけど、その積み重ねこそ重要なのでは?タイプ量減少→ミス低減→精神的余裕増加…みたいな連鎖効果もあると思うよ。
うーん、SSHの設定をちゃんと覚えたのって、そんなに昔じゃないんだよね。前は本当に、接続するたびに「あれ、このIPどこだっけ?」とか言いながら調べ直しててさ。ま、それが普通だと思い込んでた時期もあったけど…。
でも実際には`~/.ssh/config`ファイルを使えば、本当にいろんなことが楽になる。いや、正確には「楽」というより、「やっとまともになった」感じかも。
**セットアップ方法:**
例えばこんなふうに書く。
Host production
HostName 203.0.113.10
User deployer
IdentityFile ~/.ssh/production_key
ForwardAgent yes
Host staging
HostName staging.example.com
User deployer
IdentityFile ~/.ssh/staging_key
ああ、それからコマンド例だけど――(ちょっと余談になるけど今朝またタイプミスした)、
bash
ssh production "tail -f /var/log/application.log"
みたいに短縮名だけで済むわけ。ユーザー名とかホスト名とか…何度打ち間違えたか思い出したくもない。
**利用シーン:**
- 複数サーバの管理時
- 複雑な接続情報へのショートカット作成時
- 開発・ステージング・本番など環境ごとの整理時
そうそう、現場でもこういうパターン多かった。「prod-api-1」とか「stg-db-1」みたいな命名ルールが決まってて、一回把握すればもう脳死で「ssh prod-api-1」って打てるし、細かい情報は全部隠蔽できるしね。でも新メンバーが混乱せず即戦力化できるようになった事例、多分そこまで珍しくない気もする。逆に言えば、この仕組みなしだと泥沼だったとも言える。
…ところでProxyJump知ってる?バスティオン経由の場合だけど、自分最初意味不明だった(ぼーっとしてて)。でもconfig内にこう書けばいい:
Host internal-server
HostName 10.0.0.5
User admin
ProxyJump bastion
なんというか、一度慣れるともう戻れない感じ?
## 9. シェル関数・エイリアスによる反復作業自動化
同じ長ったらしいコマンドばっかり毎日手入力してた頃――いや本当に指つりそうだったんだけど、その反省からエイリアスや関数を覚え始めた記憶がある。まあ、人間は学ぶ生き物だからね…。
**セットアップ方法:**
`.bashrc`や`.zshrc`に追加する形。
# シンプルなエイリアス設定
alias k="kubectl"css
# パラメータ対応関数例
dps() {
docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}" | grep "$1"
}
**利用シーン:**
- 頻繁に使用するコマンドの短縮
- ワークフロー用カスタムツールの実装
- チーム間で複雑なコマンド統一時
Kubernetes運用では特に痛感したけど、とにかく繰り返し同じ文字列ばっかり打つ羽目になるので、次第に関数量産機になった自分…。ま、それでも効率上げられて救われた側面は否定できないかな。
Pod一覧取得とかログ追跡とかexec操作用にも色々作った:
bash
# Pod一覧簡易表示
kp() {
kubectl get pods | grep "$1"
}
bash
# Podログ追跡
kl() {
POD=$(kubectl get pods | grep "$1" | head -1 | awk '{print $1}')
if [ -z "$POD" ]; then
echo "No pod found matching: $1"
return 1
fi
kubectl logs -f "$POD" ${@:2}
}
bash
# Podへのexec操作
ke() {
POD=$(kubectl get pods | grep "$1" | head -1 | awk '{print $1}')
if [ -z "$POD" ]; then
echo "No pod found matching: $1"
return 1
fi
kubectl exec -it "$POD" -- ${@:2:-bash}
}
こういうショートカットのお陰で「kl api-server」と叩くだけですぐAPIサーバPodからログ流せたり、「ke database-pod mysql」でMySQLシェル入れたり、とても助かった瞬間多かった。うーん…単純化すると地味なんだけど、その積み重ねこそ重要なのでは?タイプ量減少→ミス低減→精神的余裕増加…みたいな連鎖効果もあると思うよ。
SSH設定ファイル整理したらサーバー名覚える必要消滅
【プロのヒント】
エイリアスや関数ってさ、なんだかんだ各自バラバラになりがちだけど…えっと、最近はチーム用のシェル設定リポジトリを作って、それをみんなが自分のプロファイルからsourceで読み込む形にしてるんだよね。まあ面倒っちゃ面倒。でも共通化できて便利。……うん、ここ大事。
## 10. 高度なコマンドでGit操作を習得
GitってDevOpsには不可欠とか言われるけど、正直ほとんどの人はほんの一部しか使いこなせてない気もするんだ。ま、私もそうかもしれない。機能多すぎ。
**プロのヒント:**
`git-awesome`みたいな名前付けたスクリプトPATH上置いておけば `git awesome` の独自コマンドとして動くようになる(地味だけどうれしい)。
## ボーナス:複数リポジトリ管理用スクリプト
今いる会社なんだけどさ――50以上もリポジトリ抱えてて、その全部クローン&更新とか想像するだけでも疲労感増す。でも放置すると後悔するタイプだから…えっと、自分用にこんなの書いた:
# 衝突回避(stash)
git stash;
# 全remote取得
git fetch --all;
# 現在ブランチ確認
current_branch=$(git rev-parse --abbrev-ref HEAD);
# 状態短縮表示
git status -s;
**使用方法:**
ざっくり言えば、このシェルを好きな場所に設置して実行権限与えるだけ。ただ、「~/.repos.txt」っていう地味なテキストファイル(URL一覧)必要だから注意ね!あと「projects」ディレクトリー忘れて作業始めたりしないよう…。あーまた話それたわ、ごめん。一応これ全部自作なので、不安だったらバックアップ取ってから試してほしいかも。
エイリアスや関数ってさ、なんだかんだ各自バラバラになりがちだけど…えっと、最近はチーム用のシェル設定リポジトリを作って、それをみんなが自分のプロファイルからsourceで読み込む形にしてるんだよね。まあ面倒っちゃ面倒。でも共通化できて便利。……うん、ここ大事。
## 10. 高度なコマンドでGit操作を習得
GitってDevOpsには不可欠とか言われるけど、正直ほとんどの人はほんの一部しか使いこなせてない気もするんだ。ま、私もそうかもしれない。機能多すぎ。
**コマンド:**
git log --oneline --graph --decorate --all -10
このコマンドね、一見地味だけど――いや実際結構役立つやつで。最近のGit履歴をぱっと視覚的に見ることができて、しかもブランチやタグまでちゃんと出てくる。不思議とこれだけで全体像わかった気になる…けど本当かな?ああ、ごめん。本題へ戻ろう。
**使用する場面:**
- 複雑なブランチ構造がカオスすぎて頭抱えたとき
- マージした瞬間「あれ?」と思った時点で調査するとき
- いつ・どこに誰が何入れたか把握しないと怒られる場合
**実例:**
前に、本番環境でインシデント発生してしまった時――もう心臓バクバクだったけど、その原因となった変更箇所をサッと特定しなくちゃならなくなった。でも手動でコミット遡るとか無理ゲーじゃない?そこで使ったのがこれ:
git bisect start
git bisect bad HEAD
git bisect good last-known-good-tag
git bisect run ./test-script.sh
Gitはコミット履歴全部相手に二分探索してくれるから、自動的にテストスクリプト走らせながら不具合入り込んだコミット探し出してくれる。「自分でも書いたっけ?」と思うくらい速攻で原因特定できたよ……いや本当に助かった。普通なら何時間も消えてただろうになぁ。
**プロのヒント:**
`git-awesome`みたいな名前付けたスクリプトPATH上置いておけば `git awesome` の独自コマンドとして動くようになる(地味だけどうれしい)。
## ボーナス:複数リポジトリ管理用スクリプト
今いる会社なんだけどさ――50以上もリポジトリ抱えてて、その全部クローン&更新とか想像するだけでも疲労感増す。でも放置すると後悔するタイプだから…えっと、自分用にこんなの書いた:
#!/bin/bash
# repo-manager.sh - 複数Gitリポジトリ管理用bash
REPO_FILE="$HOME/.repos.txt"
REPO_DIR="$HOME/projects"
bash
# リポジトリファイル無かったら空ファイル作成、と。
touch "$REPO_FILE"
bash
# コマンド関数群(名前付け結構迷った)
clone_all() {
mkdir -p "$REPO_DIR"
cd "$REPO_DIR" || exit 1
bash
echo "全リポジトリーをクローン中..."
while IFS= read -r repo; do
if [[ -n "$repo" && "$repo" != \#* ]]; then
repo_name=$(basename "$repo" .git)
if [[ ! -d "$repo_name" ]]; then
echo "クローン中: $repo"
git clone "$repo"
else
echo "既存: $repo_name"
fi;
fi;
done <"$REPO_FILE"
echo "全て$REPO_DIR にクローン済み";
}
bash
update_all() {
cd "$REPO_DIR" || exit 1;
<pre><code>
echo "全リポジトリー更新中..."
for dir in */; do
if [[ -d "$dir/.git" ]]; then;
echo "===== 更新中: ${dir%/} =====";
cd "$dir" || continue;
# 衝突回避(stash)
git stash;
# 全remote取得
git fetch --all;
# 現在ブランチ確認
current_branch=$(git rev-parse --abbrev-ref HEAD);
# 最新pull
git pull origin "$current_branch";
cd "$REPO_DIR" || exit 1;
echo "";
fi;
done;
echo "全て更新完了!";
}
</coder>
add_repo() {
if [[ -z "$1" ]]; then;
echo "使い方: repo-manager.sh add <git-repo-url>";
exit 1;
fi;
# 登録済み判定
if grep -q "^$1$" "$REPO_FILE"; then;
echo "既登録: $1";
else:
echo "$1" >>"$REPO_FILE";
echo "追加済み: $1";
fi;
}
status_all() {
cd "$REPO_DIR" || exit 1;
echo "各種ステータス表示:";
for dir in */; do:
if [[ -d "$dir/.git" ]]; then:
echo "===== ステータス: ${dir%/} =====";
cd "$dir" || continue;
# ブランチ名取得
current_branch=$(git rev-parse --abbrev-ref HEAD);
echo "Branch: $current_branch";
# 状態短縮表示
git status -s;
# リモートとの差分表示
git rev-list --count --left-right "@{upstream}"...HEAD 2>/dev/null | {
read -r behind ahead;
if [[ $behind -gt 0 ]]; then ;
echo "Behind remote by $behind commits";
fi ;
if [[ $ahead -gt 0 ]]; then ;
echo "Ahead of remote by $ahead commits";
fi ;
};
cd "$REPO_DIR" || exit 1 ;
echo "" ;
fi ;
done ;
}
case "$1" in :
clone)
clone_all ;;
update)
update_all ;;
add)
add_repo "$2";;
status)
status_all;;
help|*)
echo "Usage: repo-manager.sh <command>";
echo "Commands:";
echo " clone - リスト内すべてクローン";
echo " update - ローカル全更新";
echo " add - リストへ追加";
echo " status – 各状態確認";
echo “ help – このヘルプ出力” ;
;;
esac REPO_FILE="$HOME/.repos.txt"
REPO_DIR="$HOME/projects"
**使用方法:**
ざっくり言えば、このシェルを好きな場所に設置して実行権限与えるだけ。ただ、「~/.repos.txt」っていう地味なテキストファイル(URL一覧)必要だから注意ね!あと「projects」ディレクトリー忘れて作業始めたりしないよう…。あーまた話それたわ、ごめん。一応これ全部自作なので、不安だったらバックアップ取ってから試してほしいかも。

alias, function…長いコマンドも一言で呼べばもう別人
このスクリプトを `repo-manager.sh` という名前で保存して、そうだな…まずは実行可能にする必要がある。コマンドはたしか `chmod +x repo-manager.sh` だったかな。ちょっと待って、昔これ間違えて別のファイルに付与しちゃって焦ったことある。ああ、話が逸れた、ごめん。それで次だけど、リポジトリ追加はこうやる:`./repo-manager.sh add :org/repo1.git` 。
そして全部クローンしたいときは `./repo-manager.sh clone` を実行すればいいわけなんだけど、本当にこれで合ってたっけ?いや、大丈夫か。その後は更新ね、つまり pull 的な作業が必要なら `./repo-manager.sh update` 。
最後に現状を確認したくなる時もよくあるから、そのときは `./repo-manager.sh status` を叩く感じ。でもまあ毎回打つの面倒だなって思う時もある。</code></pre>
**例えば…** 自分が今のチームに加わった時なんだけど、環境準備とリポジトリ集めるのに3日まるまる潰れちゃったんだよね。正直、時間返してほしいレベル。でもさ、その後入社してきた人がこのスクリプト使ったら同じこと30分で終わっちゃって…。うーん、不公平?まあ、それでも助かる人増えるならいいよね。ていうか今じゃオンボーディングプロセスになっちゃって、新メンバーも初日から普通に作業始めてるし。不思議な気分。
**裏技的ヒントを一つ:** PATH にこのスクリプト追加するとか、それこそエイリアス(例えば `repos` とか)作っとけば本当に楽になる。えっと…前職ではそれ忘れてて無駄にディレクトリ移動してた自分が馬鹿みたいだった。
### コマンドライン初心者時代――そしてDevOpsウィザード?
3年前、自分まだ基本的コマンドもググりながら必死だった気がする。同僚にはさっさと抜かされて悔しかったなぁ。しかし最近になって、自分の操作見て「何その魔法?」みたいな顔されることも増えた。不思議。本当はそんな大層なことしてないのにね。いやまあ、人によっては“速そう”とか言われたりするけど、それ以前に普通に役立つ場面多いし…。ああもう、「初心者でも大丈夫」みたいな安易な慰め言いたい訳じゃないけど、この手順知っとくだけでも世界ちょっと変わると思う。
git bisectや図解ログ、リポジトリ管理スクリプトの謎
効率化って、なんだろうな。繰り返しの作業が減れば、少しは気が楽になるかも。ああ、でもツールと格闘している時間が長いと、本当に解決したい課題に集中できないんだよね。ま、いいか。実際には、目の前のタスクを片付けるのが最優先で、そのためにはまずはコマンドを1つか2つ覚えてみることから始めてみたらどうだろう。全部一気にやろうとしても無理だから、ちょっとずつね。
えっと、日々のワークフローに取り入れると、不思議と体が反応するようになってくる。チートシートを机の端っこに置いたまま、一度二度見返して、それでもまだ指が迷うこともある。でもさ、そのうち慣れていくんだと思うよ。そういえば昨日コーヒーを飲みすぎて手元が狂ったけど…まあ話を戻すと、そのあと他のコマンドにも挑戦してみるといいかな、と。
しばらく経てば、複雑な作業も案外シンプルになったりするし、時間ばかり食っていたタスクもいつの間にかサクサク進むことが増えるかもしれない。不思議なもので、人間って慣れるんだよね。いや、本当にそうなのかな? たぶんだけど。そしてさ、近いうちにジュニアエンジニアがあなたのキーボード捌きを見て、「えっ、それどうやったんですか?」みたいな顔で注目される瞬間も来たりして。それもちょっと面白い光景だよね。
このリストで何か気になったコマンドはあった?最初に試してみたいものとかある?別に大したことじゃなくてもいいから、ぜひコメントで教えてほしいな。
えっと、日々のワークフローに取り入れると、不思議と体が反応するようになってくる。チートシートを机の端っこに置いたまま、一度二度見返して、それでもまだ指が迷うこともある。でもさ、そのうち慣れていくんだと思うよ。そういえば昨日コーヒーを飲みすぎて手元が狂ったけど…まあ話を戻すと、そのあと他のコマンドにも挑戦してみるといいかな、と。
しばらく経てば、複雑な作業も案外シンプルになったりするし、時間ばかり食っていたタスクもいつの間にかサクサク進むことが増えるかもしれない。不思議なもので、人間って慣れるんだよね。いや、本当にそうなのかな? たぶんだけど。そしてさ、近いうちにジュニアエンジニアがあなたのキーボード捌きを見て、「えっ、それどうやったんですか?」みたいな顔で注目される瞬間も来たりして。それもちょっと面白い光景だよね。
このリストで何か気になったコマンドはあった?最初に試してみたいものとかある?別に大したことじゃなくてもいいから、ぜひコメントで教えてほしいな。