Tech Racho エンジニアの「?」を「!」に。
  • 開発

Mac/Linux間でシェルスクリプトの絶対パスやdateの違いを吸収する

こんにちは、hachi8833です。BPS社内Slackの#macチャンネルのやりとりからです。

160830_1932_niXaHL

パスとdateをPerlで取得

perlのrel2abs()で絶対パスを取得し、strftime()で日時を数字のみで取得しています。

ENV_PATH=$(perl -MFile::Spec -e "print File::Spec->rel2abs( \"$0\" )")
EXEC_DATETIME=$(perl -MPOSIX -e "print strftime(\"%Y%m%d%H%M%S\", localtime)")

も少し短く

続いて「こっちならもうちょっと短いよー」との意見も出ました。

160906_1505_kzMiG9

perl -MCwd -le 'print Cwd::abs_path(".")'

perlならMacとLinuxの両方でほぼ確実に利用できます。凝ったコードにするとperlのバージョンの互換性の問題が生じるかもしれないので、このようなワンライナーにとどめておくのがよいでしょう。

それにしても、Dockerコンテナ化されたプロジェクトならこういうことを気にせずに安心してシェルスクリプトを書けるのにと思います。

Rubyで書いてみた

今回の目的では使いませんが、Rubyで書くと次のような感じになりますね。

ENV_PATH=$(ruby -e "print Dir::getwd")
EXEC_DATETIME=$(ruby -e "print Time.now.strftime('%Y%m%d%H%M%S')")

補足:プラットフォーム互換について

ネタ元のmorimorihogeです。
小さなシェルスクリプトはWeb系エンジニアは嗜みとして利用されていると思います。Rails系システムであれば、定期実行にはWheneverを使ってrake taskを呼び出したり非同期実行であればDelayed::JobResqueSidekiqを使えば、ディストリビューションに依存しないバッチ処理が作成できて問題も少ないので、基本的にはそちらに倒すと楽ができます。

ただ、Webアプリを開発するチームとインフラ管理をしているチームが責任範囲や組織的に分かれている場合には、お互いの共通言語ということでシェルスクリプトを使うのがトラブルが少ないでしょう。
特にインフラ周りを担当されているエンジニアがある程度のルールを持っている場合、シェルスクリプトで書いておくことでインフラエンジニア側で後から多少修正するといったことも簡単にできるようになります。

ただ、Webアプリのシステム中にシェルスクリプトを混ぜ込む時には本記事の様にある程度プラットフォーム互換を意識して書いておかないと、開発者のMacでは動くけどstagingに持っていったときに動かないといった現象が発生してしまいます。
もちろん「このバッチはLinux環境でしか動かさないよ!」というルールで開発・運用をしても良いのですが、その場合は開発者の手元でテストされなくなって問題がスルーされてしまう可能性が高まります。

Dockerを使って・・・という解決策も確かにありますが、それはそれでDockerの使い方をサポートしたりしないといけなくて辛みもあります(弊社社内ではまだDockerを完全に標準開発環境として整備しきれていない)。
他社のエンジニアと連携して動くこともあるので、後で説明が面倒なことになるよりはおとなしくマルチプラットフォーム動作するように書いてしまった方が結果として面倒がないかな、とも思いました。

関連記事

CONTACT

TechRachoでは、パートナーシップをご検討いただける方からの
ご連絡をお待ちしております。ぜひお気軽にご意見・ご相談ください。