getopt – 外部コマンドでオプションを正規化・整形する

パラメータ展開
スポンサーリンク

getopt はコマンドライン引数から短い(-a)および長い(--alpha)オプションを解析し、シェルが扱いやすい形に整形して出力する外部コマンドです。eval set -- "$(getopt ...)" と組み合わせて安全に引数処理を行います。
実務では、長いオプション対応のCLIスクリプトや、POSIX getopts では扱いづらい可読性重視の引数仕様に使います。

構文(Syntax)

# util-linux の拡張 getopt(一般的)
getopt [OPTIONS] -- -o|--options OPTSTRING [-l|--longoptions LONGOPTS] [--] PARAMETERS...

# 典型的な利用パターン(推奨)
eval set -- "$(getopt -o OPTS -l LONGOPTS -n "$0" -- "$@")"
# その後: while case/shift で処理
  • OPTSTRING:短いオプション集合(ab:=必須引数、c::=任意引数(拡張))。
  • LONGOPTS:カンマ区切り(例:alpha,bravo:,charlie::)。
  • --getopt のオプション部と解析対象の引数を区切る必須のセパレータ。

主なオプション一覧

オプション説明使用例
-o, --options OPTSTRING短いオプション仕様を定義(:=必須、::=任意(拡張))-o ab:c::
-l, --longoptions LONGOPTS長いオプションをカンマ区切りで定義-l alpha,bravo:,charlie::
-n, --name NAMEエラーメッセージに表示するプログラム名-n "$0"
-q, --quiet解析エラーの自動メッセージを抑制-q
-Q, --quiet-output標準出力の冗長さを抑える(環境依存)-Q
-s, --shell SHELLクォート方式を指定(sh, bash, csh, tcsh など)-s bash
-u, --unquoted結果をクォートせずに出力(安全性に注意)-u
-T, --test拡張版getoptかをテスト(終了コード4-T
--getopt のオプション終端。以降は解析対象の引数-- "$@"

ポイントgetopt整形された引数列を出力するだけなので、eval set -- "$(getopt ...)" の形で現在のシェルの位置パラメータに反映してから while/case/shift で扱います。

実行例

短/長オプションを安全に解析(基本形)

説明-a(フラグ)、-b ARG--charlie[=ARG] を受け付けるスクリプトの雛形。
コマンド

cat > /tmp/cli.sh <<'SH'
#!/usr/bin/env bash
set -e

OPTS_SHORT='ab:'
OPTS_LONG='alpha,bravo:,charlie::'

# 1) 整形(失敗時は非0で終了)
PARSED="$(getopt -o "$OPTS_SHORT" -l "$OPTS_LONG" -n "$0" -- "$@")"
eval set -- "$PARSED"

a=0; bval=''; cval=''
# 2) ループで取り出し
while true; do
  case "$1" in
    -a|--alpha)   a=1; shift ;;
    -b|--bravo)   bval="$2"; shift 2 ;;
    -c|--charlie) cval="${2:-default}"; shift 2 ;;
    --)           shift; break ;;
    *)            break ;;
  esac
done

printf 'a=%s\nb=%s\nc=%s\nrest=%s\n' "$a" "$bval" "$cval" "$*"
SH
bash /tmp/cli.sh -a -b 42 --charlie=hi file1 file2

出力例

a=1
b=42
c=hi
rest=file1 file2

-- でオプション終了を明示

説明-- 以降は - から始まっても位置引数として扱います。
コマンド

bash /tmp/cli.sh -a -- -b not-option

出力例

a=1
b=
c=
rest=-b not-option

任意引数(::)の扱い(拡張)

説明--charlie を値なしで与えるとデフォルトを設定。
コマンド

bash /tmp/cli.sh --charlie

出力例

a=0
b=
c=default
rest=

エラー例:必須引数欠如で非ゼロ終了

説明-b は必須引数。欠如すると getopt がエラー終了します。
コマンド

getopt -o ab: -l alpha,bravo: -n demo -- -a -b
echo $?

出力例(例)

demo: option requires an argument -- 'b'
1

拡張版 getopt の存在確認

説明-T は拡張版で 4 を返します(存在確認に利用)。
コマンド

getopt -T; echo $?

出力例(例)

4

関連コマンド

  • getoptsシェル組み込み。短いオプション向けで移植性が高いが、長いオプションは扱えない。
  • shift:解析済み引数を削除するのに使用(eval set -- ... 後のループで利用)。
  • printf / echo:ヘルプやエラー表示の整形。
  • case:オプション分岐の本体ロジック。

備考

  • 移植性getopt は外部コマンドで実装差があります(util-linux 版、BusyBox 版、古い BSD 版等)。**POSIX標準は getopts**であり、最大限の移植性を求める場合は getopts を推奨。
  • クォート安全性:空白や特殊文字を含む引数に対しては、必ず eval set -- "$(getopt ... -- "$@")" のイディオムを使い、-- の区切りを忘れないこと。-u/--unquoted は意図が明確な場合のみ。
  • 終了ステータス:0=成功、非0=失敗。-T は 4 を返す(拡張版検出)。
  • 長いオプション= で値を渡せます(例:--bravo=value)。スペース区切りでも実装により扱えますが、= 指定が可搬で分かりやすいです。
  • BusyBox:BusyBox の getopt は機能が限定的な場合があります。--test--shell が無いこともあるため、環境毎に getopt --help で確認してください。
  • sudo:解析自体に特権は不要。通常ユーザーで実行可能です。

参考

スポンサーリンク
Bash玄

はじめまして!Bash玄です。

エンジニアとしてシステム運用に携わる中で、手作業の多さに限界を感じ、Bashスクリプトを活用して業務を効率化したのがきっかけで、この道に入りました。「手作業は負け」「スクリプトはシンプルに」をモットーに、誰でも実践できるBashスクリプトの書き方を発信しています。

このサイトでは、Bashの基礎から実践的なスクリプト作成まで、初心者でもわかりやすく解説しています。少しでも「Bashって便利だな」と思ってもらえたら嬉しいです!

# 好きなこと
- シンプルなコードを書くこと
- コマンドラインを快適にカスタマイズすること
- 自動化で時間を生み出すこと

# このサイトを読んでほしい人
- Bashに興味があるけど、何から始めればいいかわからない人
- 定型業務を自動化したい人
- 効率よくターミナルを使いこなしたい人

Bashの世界に一歩踏み出して、一緒に「Bash道」を極めていきましょう!

Bash玄をフォローする

コメント