getoptsを使用したbashでのオプションパラメータの処理

getoptsを使用したbashでのオプションパラメータの処理

オプションのパラメーターを使用して入力ファイルを処理するbashスクリプトがあります。スクリプトは次のとおりです。

#!/bin/bash
while getopts a:b:i: option
do
case "${option}"
in
a) arg1=${OPTARG};;
b) arg2=${OPTARG};;
i) file=${OPTARG};;
esac
done

[ -z "$file" ] && { echo "No input file specified" ; exit; }

carry out some stuff

スクリプトは正常に実行されますが、入力ファイルを次のように指定する必要があります。

sh script.sh -a arg1 -b arg2 -i filename

-i次のようにオプションなしでスクリプトを呼び出すことができるようにしたいと思います。

sh script.sh -a arg1 -b arg2 filename

入力ファイルを指定しないと、エラーメッセージが表示されます。これを行う方法はありますか?

答え1

#!/bin/sh -

# Beware variables can be inherited from the environment. So
# it's important to start with a clean slate if you're going to
# dereference variables while not being guaranteed that they'll
# be assigned to:
unset -v file arg1 arg2

# no need to initialise OPTIND here as it's the first and only
# use of getopts in this script and sh should already guarantee it's
# initialised.
while getopts a:b:i: option
do
  case "${option}" in
    (a) arg1=${OPTARG};;
    (b) arg2=${OPTARG};;
    (i) file=${OPTARG};;
    (*) exit 1;;
  esac
done

shift "$((OPTIND - 1))"
# now "$@" contains the rest of the arguments

if [ -z "${file+set}" ]; then
  if [ "$#" -eq 0 ]; then
    echo >&2 "No input file specified"
    exit 1
  else
    file=$1 # first non-option argument
    shift
  fi
fi

if [ "$#" -gt 0 ]; then
  echo There are more arguments:
  printf ' - "%s"\n' "$@"
fi

そのコードには具体的な内容がないので、にbash変更させていただきます。shbash

答え2

拡張したいスティーブン・チャジェラス使用に良い答えバシズム質問スタイルに関する追加情報、つまり[ -z "$file" ] && { echo "No input file specified" ; exit; }- を使用する代わりにもし

#!/bin/bash
unset -v file arg1 arg2

while getopts "a:b:i:" option; do
    case "$option" in
        a ) arg1="$OPTARG";;
        b ) arg2="$OPTARG";;
        i ) file="$OPTARG";;
        * ) exit 1;;
    esac
done

shift "$((OPTIND - 1))"

[ -z "$file" ] && [ "$#" -eq 0 ] && { echo "No input file" >&2; exit 1; }
[ -z "$file" ] && [ "$#" -gt 0 ] && { file="$1"; shift; }

echo "DEBUG: arg 1 is $arg1"
echo "DEBUG: arg 2 is $arg2"
echo "DEBUG: file  is $file"

[ "$#" -gt 0 ] && { echo "More arguments"; printf " - %s\n" "$@"; }

関連情報