#tl;dr
クロスプラットフォームするなら
スクリプトの一行目はこれで書こうね、の話
#!/usr/bin/env bash
# 以下だと困るケースがある:
#!/bin/sh
#!/bin/bash
#!/opt/homebrew/bin/bash
経緯
アプリ用データ/ePub作成からML用まで、「画像の出し入れ」用の各種スクリプトを書いているのですが、
以下の遍歴で継ぎ足してきたスパゲッティになっています:
1. ローカルMac用 (自分だけ使ってた頃)
2. Linuxサーバ用 (みんなで使おうね版)
3. クラウド(Docker)用 (お客さんも使ってね版)
なんですが、数年間継ぎ足しを続けてる間に保守が大変になってきました。
Docker で全部やっちゃえばよくね?
一時期、「Docker用をローカル」でも使ってたんですが、
そこに出てきたApple Silicon。
フルに性能を活かすなら今はまだローカルで動かすのが最善なようで。
中身は imagemagick と poppler を諸々オプション付けて GNU Parallel で実行するだけのスクリプトなので
移植性は本来そんなに悪く無いはずなのです。
そんなわけで基本のキ、「shebangの書き方」からちゃんと整理する事にしました。
正解はこれ
#!/usr/bin/env bash
ほぼどのOSでも、確実にbashを呼び出してくれます
僕の環境で正解じゃなかったけどよく見る書き方 1
#!/bin/sh
元祖にして至高、これ以外だとぶん殴るって方もいるのですが
これだと下記のように「どのシェルが呼ばれるかわからない」問題が発生します。
対策は「どのシェルでも動くように書け」なんですが、すでにあるコード資産(bash専用/zshはNG)があるのを宗教上の理由だけで書き直すのは何かの哲学に反する気がするので今回はNG
/bin/sh で呼ばれるシェル一覧:
Ubuntu : dash 又は bash
Mac (10.13以前) : bash 3
Mac (10.14以降) : zsh 5.8 又は bash 3
Mac (Homebrew で bash 入れて chsh した) : bash 5.1
僕の環境で正解じゃなかったけどよく見る書き方 2
#!/bin/bash
今試したらOSX内蔵の bash3.2 が開きました。
現行のBash5系に統一したいのでNG。
(MacOS 10.14後期以降、zsh へのエイリアスに変更されたとか目にした気がしたんだけど勘違いだったのかな)
僕の環境で正解じゃなかったけどよく見る書き方 3
#!/opt/homebrew/bin/bash
これはレアケースかと思いますが、MacのHomebrewの標準インストールパスです。
Bash5を明示して使いたい場合にこう書くマカーの方も居たんですが、
当然Linuxではエラーで動かなくなります。
「DockerがM1対応するの待てば良いのに」
RC版が出ましたね。
なんだけどそこにM1があったので。
M1マヂはええっすわ。すんごい快適