シェルスクリプトのコードを整形してくれるツール `shfmt`

2023-02-15Bash,CentOS,Linux,Ubuntu

シェルスクリプトでコーディングする際に使っているツールを紹介。
( とりあえず殴り書きして、コードフォーマットツールに食わせて整形します。 )

GitHub - mvdan/sh: A shell parser, formatter, and interpreter (POSIX/Bash/mksh)

必要なもの

  • Go
    • Macなら brew install golang
    • CentOSなら yum install golang

インストール方法

Gihtubのshfmtトップページ にインストール方法が書かれています。

2019-02-15現在、 go コマンドが使えれば、以下のコマンドだけでインストールされます。

$ go get -u github.com/mvdan/sh/cmd/shfmt

正常にインストールされていれば、以下のフォルダにコマンドがインストールされています。

# 僕の環境
$ uname -moi
x86_64 MacBookPro10,1 Darwin

$ bash -version
GNU bash, バージョン 5.0.2(1)-release (x86_64-apple-darwin18.2.0)

# HOMEディレクトリ配下にコマンドがインストールされている
$ cd
$ ls .go/bin/shfmt
.go/bin/shfmt*

# 頻繁に使うので、 `$HOME/.go/bin` にパスを通しておく
echo 'export PATH="$PATH:$HOME/.go/bin"' >> ~/.bashrc

# コマンドが実行できるか確認
$ shfmt --help

※ちなみに、CentOS7系サーバでセットアップを行うと、 $HOME/.go ではなく $HOME/go ディレクトリにコマンドがインストールされます。なぜパスが違う??

実行方法

以下のようなコードを用意。
( test.sh というファイル名で作成 )

#!/usr/bin/env bash

echo "test1"

if [[ 1 = 2 ]];
then
    echo "test2"
fi

  echo "test3"

case $# in
0)
  echo '引数なし'
    ;;
*)
  echo '引数あり'
  ;;
esac

echo "ありがとう" &&
  echo "そしてありがとう"

フォーマッタを適用するには、コマンド引数にファイルを指定します。

$ shfmt test.sh

#!/usr/bin/env bash

echo "test1"

if [[ 1 == 2 ]]; then
        echo "test2"
fi

echo "test3"

case $# in
0)
        echo '引数なし'
        ;;
*)
        echo '引数あり'
        ;;
esac

echo "ありがとう" &&
        echo "そしてありがとう"
  • オプションを指定しないと使いにくい
    • インデントはタブになっている
    • switch-caseをインデントしない
    • &&| を先頭に持ってきてくれない

なので、以下のような alias を設定し使っています。(オプションの詳細は shfmt --help を参照。)

alias shfmt='$HOME/.go/bin/shfmt -i 2 -ci -bn -s'

設定後、再度実行。

$ shfmt test.sh
#!/usr/bin/env bash

echo "test1"

if [[ 1 == 2 ]]; then
  echo "test2"
fi

echo "test3"

case $# in
  0)
    echo '引数なし'
    ;;
  *)
    echo '引数あり'
    ;;
esac

echo "ありがとう" \
  && echo "そしてありがとう"

ちなみに、デフォルト挙動ではフォーマット結果を標準出力に書き出すので、ファイルを上書きしたい場合は -w オプションを付けましょう。

$ shfmt -w test.sh

2023-02-15Bash,CentOS,Linux,Ubuntu