要件として外部からPython等のプログラミング言語の導入やライブラリのインストールを制限されているもしくは禁止といった環境でプログラム的処理をするにはシェルスクリプトが選択肢となってきます。
シェルスクリプトは近代的ツールでも前処理として使ったり、ちょっとした用途で使うにはまだまだ需要があります。ここではそういった小規模な使い方ではなく中大規模な比較的ガッツリとプログラム開発としてシェルスクリプトを使う場合を想定します。
ですが、シェルスクリプトはバグが混入しやすいものです。プログラム開発には向いていません。少しでもバグを減らすには過去のノウハウの利用とツールを駆使すべきです。
シェルスクリプトは基本的にはコマンドのリストです。と、割り切っておくとイラつくことは多少なりとも軽減できます。
以下、工事中
コーティング規約
シェルスクリプトの問題の一つは可読性の低いコードになりがちな点です。意識してコメントを入れたりテクニカルなワンライナーを多用しないようにした方がよいと思います。
可読性、保守性を保つためにコーディング規約を定めてソレに沿ったプログラミングがよいです。コーディング規約がない場合は、比較的有名なGoogleのコーディング規約Shell Style Guideが使えると思います。少ない労力で統一するにはコード整形ツールを使うと良いでしょう。
Strict Mode
正式なものではないですが、Strict Mode設定として出回っている設定として
set -euo pipefail
があります。
意図しないエラーを減らすために有効そうですが、エラーを想定したコードもありえるので場合によっては使わなかったり、オプション内容を変更して使うのもアリだと思います。
Unofficial bash strict mode
Unofficial bash strict mode. GitHub Gist: instantly share code, notes, and snippets.
型
基本的にはシェルスクリプトに型は無い、と思っておいたほうが良いです。基本的に文字列です。
変数に対してlocal, declare, typeset等がありますが型(というか属性)の違う値を入れてもそのまま動いてしまう場合があるので注意が必要です。高級言語と同じような期待をしてはいけません。readonlyは比較的期待通りに動くので積極的に使っていきたいです。
使ったことはないですが、静的型付けを行いシェルスクリプトに変換する言語(トランスパイル)Cotowaliがあります。一般的な言語に近く理解しやすい文法らしいのでこういったものは有用かもしれません。しかし、学習コストがどのくらいかかるのかわかりません。
GitHub – cotowali/cotowali: A statically typed scripting language that transpile into POSIX sh
A statically typed scripting language that transpile into POSIX sh – GitHub – cotowali/cotowali: A statically typed scripting language that transpile into POSIX sh
整数
ErrorになりそうなケースもErrorにならないので注意が必要です。特にダブルクォーテーションを使うケースの場合は事前にバリデーションやノーマライズが必要かもしれません。
bash --version set -x declare -i var # 整数 var=10 echo "var=10: ${var}" var=10.5 # 小数点あり Errorになる echo "var=10.5: ${var}" var=010 # 8進数 echo "var=010: ${var}" var=0x10 # 16進数 echo "var=0x10: ${var}" var=abc # 文字列 Errorにならない echo "var=abc: ${var}" var=@\\\%\&\! # 記号 Errorになる (計算式として認識?) echo "var=@\\\%\&\!: ${var}" var=+10 # 式 echo "var=10: ${var}" var=-10 # 式 echo "var=10: ${var}" var=15-10 # 式 echo "var=15-10: ${var}" var=true # true (文字列として認識?) echo "var=true: ${var}" var=false # false (文字列として認識?) echo "var=false: ${var}" # ダブルクォーテーションを使った場合 echo "ダブルクォーテーションを使った場合" var="" # 値なし echo ${var} echo "var=\"\": ${var}" var="10" echo "var=\"10\": ${var}" var=" 10" # 左側にスペースあり echo "var=\" 10\": ${var}" var="10 " # 右側にスペースあり echo "var=\"10 \": ${var}" var=" 10 " # 両側にスペースあり echo "var=\" 10 \": ${var}" var="+ 10" # 数式とスペース echo "var=\"+ 10\": ${var}" var=" - 10 " # 数式とスペース echo "var=\" - 10 \": ${var}" var="2* 10" # 数式とスペース echo "var=\"2* 10\": ${var}" var="022* 10" # 8進数 数式にスペース echo "var=\"022* 10\": ${var}" var=" 0x10 * -10 " # 16進数 数式にスペース echo "var= 0x10 * -10: ${var}" var="foo=456" # 代入式 echo "var=\"foo=456\": ${var}" echo "foo=: ${foo}" var="foo = $foo$foo" # 代入式 echo "var=\"foo = \$foo\$foo\": ${var}" # エスケープしても認識されてしまう echo "foo=: ${foo}" var="foo=true" # 代入式 echo "var=\"foo=true\": ${var}" echo "foo=: ${foo}" var="foo=false" # 代入式 echo "var=\"foo=false\": ${var}" echo "foo=: ${foo}" readonly foo; echo "var=\"foo=789\": ${var}" # readonly変数へ代入 Errorなし echo "foo=: ${foo}"
周辺ツール関連
静的解析ツール
shellcheckはコードを解析して誤動作を起こしやすそうな書き方を指摘したりよりベターな書き方を指摘してくれます。中規模以上のスクリプトを書くときは必須と言えるツールではないでしょうか
GitHub – koalaman/shellcheck: ShellCheck, a static analysis tool for shell scripts
ShellCheck, a static analysis tool for shell scripts – GitHub – koalaman/shellcheck: ShellCheck, a static analysis tool for shell scripts
テストフレームワーク
GitHub – kward/shunit2: shUnit2 is a xUnit based unit test framework for Bourne based shell scripts.
shUnit2 is a xUnit based unit test framework for Bourne based shell scripts. – GitHub – kward/shunit2: shUnit2 is a xUnit based unit test framework for Bourne based shell scripts.
GitHub – bats-core/bats-core: Bash Automated Testing System
Bash Automated Testing System. Contribute to bats-core/bats-core development by creating an account on GitHub.
GitHub – shellspec/shellspec: A full-featured BDD unit testing framework for bash, ksh, zsh, dash and all POSIX shells
A full-featured BDD unit testing framework for bash, ksh, zsh, dash and all POSIX shells – GitHub – shellspec/shellspec: A full-featured BDD unit testing framework for bash, ksh, zsh, dash and all …
ShellSpec – シェルスクリプト用のフル機能のBDDユニットテストフレームワーク – Qiita
ShellSpec はシェルスクリプト用に開発した BDD ユニットテストフレームワークです。初期版公開以降、多くの機能を追加しておりフル機能と言えるまでに成長したのですが公式サイトはほとんど更新しておらずその機能を伝えきれなくなって…
整形ツール
EditorConfigは各種エディターのプラグインとして提供されており、タブ幅やインデントをスペースにするかどうか等設定をもたせることができます。複数エディターを使っている場合、共通した設定で使えるので便利です。
EditorConfig
EditorConfig is a file format and collection of text editor plugins for maintaining consistent coding styles between different editors and IDEs.
shfmtがデファクトスタンダードらしいです。.editorconfigを参照してくれるようなのでいいですね。
GitHub – mvdan/sh: A shell parser, formatter, and interpreter with bash support; includes shfmt
A shell parser, formatter, and interpreter with bash support; includes shfmt – GitHub – mvdan/sh: A shell parser, formatter, and interpreter with bash support; includes shfmt
別途バイナリをこちらからインストールすれば使えます。
Visual Studio Code
近年のエディターはプラグインでSSHができたりエディター自身の動作を変えたりと様々な機能拡張が可能でリッチになっています。その分、多少動作は重くなりますがそのコスト以上の恩恵を得られると思います。VScodeは最近の定番ではないでしょうか。
ここで紹介している幾つかのツールもプラグインで連携できるのでワンプレイスでリアルタイムに動作してくれるのはありがたいです。
Visual Studio Code – Code Editing. Redefined
Visual Studio Code is a code editor redefined and optimized for building and debugging modern web and cloud applications. Visual Studio Code is free and available on your favorite platform – Linux, macOS, and Windows.
Bash Beautify
EditorConfig for VS Code
Bash Debug
ShellCheck
shell-format
Playground
動作を手軽に確認できる環境として利用できます。
https://secure.sakura.ad.jp/cloud-shell/cpanel/
https://www.tutorialspoint.com/execute_bash_online.php
https://www.mycompiler.io/new/bash
https://www.jdoodle.com/test-bash-shell-script-online/
https://paiza.io/ja/projects/new?language=bash
コードジェネレーター
スクラッチからコードを書くより今後はこのようなツールの利用が主流になるのかもしれません。著作権や品質が気になるので現時点では参考程度の利用でしょうか。今後はオープンソースのライセンスのような考え方やテストも含めたのコード生成を行う等になるかもしれません。時間によって解決されるのでしょう。
$((算術式))
Bash $((算術式)) のすべて – A 基本編 – Qiita
Bash の算術式の基本について詳細に解説します! ※この記事は AdC 2016 Shell Script 4日目 Bash $((算術式)) のすべて – Qiita の衛星記事です (が、実のところこちらの記事のほうが実用性が高…
よく使いそうなコマンド
sed
sedでこういう時はどう書く? – Qiita
シェルでデータ加工するときSEDをよく使いますが、その利用例と覚え書きです、参考になれば sedコマンドはLinux/Unix/BSD/OSXに標準で入っているので、Macの人なら覚えておくと捗るかも(Linuxとは少し違うのでそこは…