Open12

Shell Script (Bash) メモ

kota65535kota65535

よく使うおまじない

#!/usr/bin/env bash
set -euo pipefail
# set -x
export LC_ALL=C
  • #!/usr/bin/env bash
    • Shebangで明示的に bash を指定
    • ディストリにより shbash とは限らないため
  • set -e
    • 非ゼロでコマンドが終了したら強制終了
  • set -u
    • 未定義の変数が参照されたら強制終了
  • set -o pipefail
    • パイプの途中でも非ゼロでコマンドが終了したら強制終了
  • export LC_ALL=C
    • Cロケールに設定
kota65535kota65535

スクリプトを置いてあるディレクトリにcdしてそのパスを保存する

SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
kota65535kota65535

ファイルをリストアップして配列に代入する。プロセス置換を利用

mapfile -t FILES < <(find . -name foo -type f)

Globを使うのが手っ取り早いが、マッチするファイルが無い場合にパターンがそのまま FILES に代入されてしまう。この挙動を避けるには shopt -s nullglob を使うと良い

FILES=(foo*)
kota65535kota65535

標準エラー出力にechoする関数

eecho() { echo "$@" 1>&2; }

標準エラー出力に赤色でechoする関数

eecho_red() { local args=("$@"); eecho -e "${args[@]: -2:1}" "\e[31m${args[*]: -1}\e[m"; }
kota65535kota65535

grep, awk, sed は GNU版とBSD版でオプションが異なる。ローカルのMacで動いていたのがCI上のLinuxで動かないみたいなことが起きる。そこでPerlを使う。

  • perl as grep
perl -nle 'print "$1" if /^(\w.*):/' .github/paths-filter.yml
  • perl as awk
perl -anle  'print "  $F[0] = \"$F[1]\""' .tool-versions
  • perl as sed
perl -i -pe "s/=\s*\"(.*)\"/= \"\"/g" versions.auto.tfvars
kota65535kota65535

usage をヒアドキュメントで表示

usage() {
  cat 1>&2 <<EOF
Description:
  Awesome script
Usage:
  bash $(basename "$0") --env <env> [--profile <profile>] <arg1> <arg2>
Arguments
  arg1 : Argument 1
  arg2 : Argument 2
Options:
  --env     : Environment name
  --profile : Profile name
EOF
kota65535kota65535

Glob系オプション

shopt -s nullglob dotglob extglob
  • nullglob
    • Globの結果が空の場合にちゃんと空のリストになってくれる
    • 何かデメリットあってデフォのおまじないから外した記憶があるんだが何だったけな…
  • dotglob
    • Globの結果にドットから始まるファイルを入れてくれる
  • extglob
    • ちょっと機能が増えたGlobが使える
kota65535kota65535

配列が文字列を含むか否か

ary=(aaa bbb ccc)
if [[ " ${ary[*]:-} " =~ \ aaa\  ]]; then
  echo "matched"
fi