💡 この記事の3行まとめ
docker logs -fの出力がマウスで選択できないのは、追記され続けるストリームを選択範囲が追いかけられないからです。- 裏技は「コピーできる形に変換する」ことではなく、画面に出ている文字をそのまま囲んで読むことにあります。
- Mac専用OCR翻訳『Zipp』は
⌃Sで囲んで 0.3秒、Apple Visionの端末内処理。無料でダウンロード(登録不要)、1日15回まで使えます。
📌 この記事の対象読者
docker logs -fの出力をドラッグしても選択できず、いらいらした経験のある方docker compose logsの色付きログをコピーしたら、記号まみれになった方- ログをコピーするためだけに
> log.txtへリダイレクトする手間をなくしたい方
コピーできないのは、あなたの操作が悪いからではない
Docker のログを読もうとして、まず手が止まるのがこの瞬間です。docker logs -f <container> を実行し、出てきた英語の行をマウスでなぞる。ところが指を離す前に新しい行が下に追加され、選択範囲がずれる。あるいは行を選択した瞬間に、画面が1行スクロールして選択が解除される。結果として、クリップボードには中途半端な文字列しか入りません。
これは操作の誤りではありません。追記型のストリームを、静的なテキストとして扱おうとしていることが原因です。docker logs は「ファイルを開いて読む」コマンドではなく、「コンテナの標準出力に溜まっている内容を流し込む」コマンドです。-f(follow)を付ければ、その流れは止まりません。止まらない流れの上で範囲を決めるのは、原理的に不安定です。
同じ問題は別の形でも現れます。docker compose logs はサービス名ごとに色を付けます。この色はANSIエスケープシーケンスという制御文字で実現されているため、そのままコピーすると [36m のような見えない記号が混ざります。貼り付け先のエディタや翻訳サービスでは、この記号が本文として扱われることがあります。検索しても目的の文字列に当たらないのは、このせいです。
さらに、less や more にパイプした場合は別の壁が立ちます。これらのページャは「代替画面」という別の描画領域を使うため、表示されている内容がターミナルのスクロールバッファに残りません。マウスで選択しても、コピーされるのは画面の見た目ではなく別の内容になることがあります。Ctrl + C で抜けた瞬間にログが消えるのも、同じ理由です。
ここまでくると分かります。コピーできないのは Docker の不具合でも、ターミナルの不出来でもありません。「流れるログを、流れないテキストとして運ぼうとする」という前提が、この環境では成立しないのです。だから必要なのは、コピーの仕方を工夫することではなく、コピーを経路から外すことです。
解決策:コピーを経路から外し、画面のまま読む
手順1:流れを止める。ただしファイルには落とさない
最初に、読む対象を確定させます。-f を付けているなら、Ctrl + C で一度止めます。止めた時点で表示されている内容が、いま読みたい範囲です。
ここでやりがちなのが docker logs <container> > /tmp/log.txt とファイルに落としてから開く方法です。確実ではありますが、読みたい行を探すために別のアプリを開くことになり、経路が伸びます。しかもファイルは溜まり続けるので、後片付けも発生します。
おすすめは、流れを止めたあとに表示されている行数を減らすことです。docker logs --tail 40 <container> のように末尾だけを出せば、画面に収まる量になります。画面に収まっていれば、スクロールも選択のずれも起きません。読む範囲が物理的に固定されるので、以降の操作が安定します。
手順2:色と記号を落とす
次に、制御文字を外します。docker compose logs --no-color を付けると、ANSIエスケープシーケンスが出力されなくなります。--no-log-prefix を併用すると、サービス名の接頭辞も外れて本文だけになります。
この2つを付ける理由は、記号を消すためだけではありません。訳したときに、記号が日本語の文に混ざらないようにするためです。制御文字が残ったまま翻訳にかけると、訳文の途中に見えない文字が入り、貼り付け先で行が崩れることがあります。入り口で落としておけば、後段のトラブルが消えます。
docker logs には --no-color がないため、色が必要ない場面では --tail と組み合わせて必要な行だけを出します。コマンドを覚えるのではなく、「記号を落とす」「行数を絞る」という2つの目的で覚えると、どのサブコマンドでも応用が効きます。
手順3:コピーせず、画面のまま囲む
ここが本題です。行数を絞り、記号を落としたら、その画面をそのまま囲みます。⌃S(Control + S) を押し、読みたい行のブロックをドラッグするだけです。クリップボードを経由しません。
この方法が効くのは、OCRが画面に描画されている文字を読むからです。ターミナルの内部バッファや選択状態ではなく、見えているピクセルを認識します。したがって、選択できないストリームであっても、代替画面のページャであっても、色付きのログであっても、見えていれば読めます。囲み終えると 0.3秒 で訳が最前面に表示され、元のターミナルは隠れません。
Apple Vision による端末内処理なので、ログの内容は Mac の外に出ません。社内のイメージ名やホスト名が含まれていても、送信可否を悩む必要がありません。コピーという工程を消すことが、いちばん確実な裏技です。
ログの読み方を比べる
【流れるログ】
従来:-f の追記で選択範囲がずれ、失敗しやすい
Zipp:画面に出ている行をそのまま囲める
【色付きログ】
従来:制御文字が混入し、検索や貼り付けが壊れる
Zipp:見えている文字を読むため、記号の混入がない
【ページャ表示】
従来:代替画面のため、スクロールバッファに残らない
Zipp:表示中の画面をそのまま対象にできる
【前処理】
従来:--no-color やリダイレクトの準備が必要
Zipp:前処理なしで、見えた瞬間に囲める
【作業の流れ】
従来:別アプリへ切り替えて戻る必要がある
Zipp:最前面に訳が出るので、ターミナルから離れない
【試しやすさ】
従来:端末やシェルの設定に依存する
Zipp:無料でダウンロード(登録不要)/1日15回まで
よくある質問(FAQ)
Q. それでもコピーしたい場面はあります。どうすればいいですか? A. コピーが必要なのは、ログを他の人に共有する場合や、issue に貼る場合です。その用途なら docker logs --tail 100 <container> 2>&1 | pbcopy のように、最初からクリップボードへ直接流すほうが確実です。読むためのコピーと、共有するためのコピーを分けると考えてください。読むだけなら囲めば足ります。
Q. ⌃S はターミナルの機能停止(フロー制御)と衝突しませんか? A. シェルによっては Ctrl + S が出力を止めるキーとして割り当てられています。その場合は stty -ixon を実行して無効化しておくと、以降は競合しません。設定はシェルの起動ファイルに1行書いておけば済みます。
Q. 画面に収まらない長いログはどうすればいいですか? A. 全部を一度に読む必要はありません。Docker のログは原因が先頭か末尾に寄ることが多いので、--tail で末尾を、必要なら --since 10m で時間を絞ってください。絞った範囲を囲み、結論が掴めなかったときだけ範囲を広げる。この順序なら、囲む回数も少なく済みます。
Q. 1日15回で足りないほどログを読みます。 A. 15回は囲む操作の回数です。1回の囲みで複数行をまとめて読めるため、実際に処理できる行数はもっと多くなります。まずは「起動失敗」「ビルド失敗」「ヘルスチェック失敗」のように、判断が止まる場面を選んで使うと収まります。
コピーできないのは、コピーしなくていい合図
docker logs の出力が選択できないとき、私たちはコピーの仕方を工夫しようとします。しかし追記されるストリーム、色付きの出力、代替画面のページャという3つは、いずれも「静的なテキストとして運ぶ」という前提を裏切る仕様です。ならば前提のほうを変える。行数を絞り、記号を落とし、見えている画面をそのまま囲む。この3手で、経路からコピーが消えます。
今日の作業で一度だけ、docker logs --tail 30 の出力を ⌃S で囲んでみてください。選択できなかった行が、そのまま日本語で読めるはずです。その手触りが、リダイレクトやページャ設定を調べるより先に効きます。
▼ 無料でダウンロード(登録不要・1日15回まで)
zipp-mac.surge.sh