大規模シェルスクリプト運用から学んだ、保守性の重要性

アイキャッチ画像

はじめに

これまで、PythonやReact、FastAPIなどを用いた開発を経験してきました。

その中で、個人的に想像以上に苦戦したのがシェルスクリプトです。

シェルスクリプトは一見するとシンプルな記述に見えますが、実際の現場では、

  • パス
  • 権限
  • コマンド実行結果
  • DockerやGitコマンドとの組み合わせ
  • エラー原因の調査

など、ハマりどころが非常に多く、他のプログラミング言語とは異なる難しさがありました。

また、書き方にも幅があるため、レビュー時に「どの書き方が良いか」で宗教論争のようになることもありました。

本記事では、実際の現場でシェルスクリプトに苦戦した経験や、そこから学んだことについて書いていきます。

苦戦した現場でのシェルスクリプト活用

この現場では、ローカル開発環境の構築や各種セットアップ処理にシェルスクリプトが使われていました。

シェルスクリプト全体の規模は非常に大きく、合計すると数万ステップ規模になっていました。

また、1つのコマンド実行で大量の処理が動く構成になっており、ゼロから環境構築を行う場合は完了まで20分近くかかることもありました。

そのため、

  • どこで何をしているのか分かりづらい
  • 一部だけ確認したくても全体実行になりやすい
  • エラー原因の特定が難しい

など、キャッチアップや調査にかなり苦戦しました。

実際にどのような点で苦戦したか

特に苦戦したのは、「どこで何をしているのか把握しづらい」ことでした。

シェルスクリプトの中では、

  • Dockerコマンド
  • Gitコマンド
  • ファイルコピー
  • 環境変数設定
  • 別シェルスクリプト呼び出し

など、多数の処理が連続して実行されていました。

さらに、シェルスクリプトの中から別スクリプトを呼び出していることも多く、処理の流れを追うだけでもかなり大変でした。

また、コメントがほとんど書かれていなかったため、

  • なぜこの処理が必要なのか
  • どのタイミングで実行される想定なのか
  • どの環境を前提としているのか

などをコードから推測しながら読み解く必要がありました。

エラー発生時も、

  • Docker側の問題なのか
  • パスの問題なのか
  • 権限の問題なのか

などの切り分けが難しく、原因特定に時間がかかることもありました。

例えば、「ファイルが存在しない」というエラーでも、実際にはかなり前段の処理でファイル生成に失敗していたり、条件分岐によって処理自体が実行されていなかったりすることもありました。

そのため、単純にエラー文を見るだけでは解決できず、「どのタイミングでファイルが生成される想定なのか」を処理全体から追う必要がありました。

さらに、環境構築全体の完了まで20分近くかかるため、修正後の再確認にも時間がかかりました。

この現場から学んだこと

この現場を経験して感じたのは、シェルスクリプトでは「一度に多くをやりすぎないこと」が重要だということです。

1回のコマンドで全体処理を実行できることは便利ですが、その分、

  • どこで失敗したのか分かりにくい
  • 一部だけ調査しづらい
  • 影響範囲を把握しづらい

といった問題も発生しやすくなります。

そのため、多少コマンド実行回数が増えたとしても、処理単位を小さく分割し、「このスクリプトを実行すると何が行われるのか」を明確にすることが重要だと感じました。

また、コメントについても、「書かなくても分かるだろう」ではなく、

  • なぜこの処理が必要なのか
  • 何を前提としているのか
  • どのような目的で実行するのか

などを細かく残すことが、長期的な保守や引き継ぎでは非常に重要だと感じました。