19
14

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

#!/bin/sh じゃないよ! #!/usr/bin/env bash だよ!! Mac/Linuxの海を泳ぎ切る話

Last updated at Posted at 2021-03-24

#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マヂはええっすわ。すんごい快適

19
14
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
19
14

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?