Shell スクリプトへのコマンドライン引数の渡し方と活用

シェルスクリプトにおいて、実行時に外部から値を渡すことは頻繁に行われる基本操作です。この仕組みにより、スクリプトの挙動を実行時に入力に応じて動的に制御できます。本稿では、位置パラメータの取り扱い、検証、および安全な利用方法について解説します。

1. 位置パラメータの構造

スクリプト起動時にスペース区切りで指定された文字列は、自動的に位置パラメータとして割り当てられます。たとえば、./deploy.sh prod /var/www/html を実行した場合、prod が第1引数($1)、/var/www/html が第2引数($2)になります。

主な特殊変数:

  • $0:実行中のスクリプトファイル名(パス付き)
  • $1$9:1〜9番目の引数(10以降は${10}のように中括弧必須)
  • $#:引数の総数
  • $@:各引数を個別にクォートされた状態で展開("$1" "$2" ...
  • $*:すべての引数を単一の文字列として展開("$1 $2 ..."

2. 実践的な引数利用例

以下は、環境名と出力先パスを受け取り、ログディレクトリを生成するスクリプトです:

#!/bin/bash

# 引数が2つあるか確認
if [[ $# -lt 2 ]]; then
  echo "エラー: 環境名と出力パスを指定してください。"
  echo "使用例: $0 staging /tmp/logs"
  exit 2
fi

ENV_NAME="$1"
OUTPUT_PATH="$2"

# セーフなパス展開(空白・特殊文字対応)
mkdir -p "$OUTPUT_PATH/$ENV_NAME"
echo "ディレクトリ作成完了: $OUTPUT_PATH/$ENV_NAME"

実行結果例:
./setup.sh dev "/home/user/app logs"/home/user/app logs/dev が作成されます。

3. 安全な引数処理のポイント

  • クォートの徹底:変数展開時は必ずダブルクォートで囲む(例:"$1")。未クォートの$1はワード分割・グロブ展開を引き起こす危険があります。
  • 引数の存在チェック:必須引数は[[ -z "$1" ]][[ $# -eq 0 ]]で事前に検証。
  • shiftによる逐次処理:複数オプションを順次処理したい場合、shiftで引数リストを左シフト可能($1が消え、$2$1に移動)。

4. 複数引数のバッチ処理

以下は、任意数のファイルパスを受け取り、それぞれのサイズを表示するスクリプトです:

#!/bin/bash

if [[ $# -eq 0 ]]; then
  echo "ファイルパスを1つ以上指定してください。"
  exit 1
fi

for file_path in "$@"; do
  if [[ -f "$file_path" ]]; then
    size_bytes=$(stat -c "%s" "$file_path" 2>/dev/null)
    echo "[$file_path] → $(numfmt --to=iec-i "$size_bytes")"
  else
    echo "警告: '$file_path' は存在しません。"
  fi
done

この例では"$@"を使い、各引数を独立して安全に反復処理しています。

タグ: bash shell-scripting command-line-arguments linux-cli

7月28日 22:54 投稿