たとえば、次の行で呼び出されるスクリプトがあるとします。
./myscript -vfd ./foo/bar/someFile -o /fizz/someOtherFile
またはこれ:
./myscript -v -f -d -o /fizz/someOtherFile ./foo/bar/someFile
それぞれの場合(または 2 つの組み合わせ)で$v
、、、$f
が$d
すべて に設定されtrue
、 と$outFile
等しくなるようにこれを解析する受け入れられた方法は何ですか/fizz/someOtherFile
?
ベストアンサー1
Bash スペース区切り(例--option argument
:)
cat >/tmp/demo-space-separated.sh <<'EOF'
#!/bin/bash
POSITIONAL_ARGS=()
while [[ $# -gt 0 ]]; do
case $1 in
-e|--extension)
EXTENSION="$2"
shift # past argument
shift # past value
;;
-s|--searchpath)
SEARCHPATH="$2"
shift # past argument
shift # past value
;;
--default)
DEFAULT=YES
shift # past argument
;;
-*|--*)
echo "Unknown option $1"
exit 1
;;
*)
POSITIONAL_ARGS+=("$1") # save positional arg
shift # past argument
;;
esac
done
set -- "${POSITIONAL_ARGS[@]}" # restore positional parameters
echo "FILE EXTENSION = ${EXTENSION}"
echo "SEARCH PATH = ${SEARCHPATH}"
echo "DEFAULT = ${DEFAULT}"
echo "Number files in SEARCH PATH with EXTENSION:" $(ls -1 "${SEARCHPATH}"/*."${EXTENSION}" | wc -l)
if [[ -n $1 ]]; then
echo "Last line of file specified as non-opt/last argument:"
tail -1 "$1"
fi
EOF
chmod +x /tmp/demo-space-separated.sh
/tmp/demo-space-separated.sh -e conf -s /etc /etc/hosts
上記のブロックをコピーして貼り付けた出力
FILE EXTENSION = conf
SEARCH PATH = /etc
DEFAULT =
Number files in SEARCH PATH with EXTENSION: 14
Last line of file specified as non-opt/last argument:
#93.184.216.34 example.com
使用法
demo-space-separated.sh -e conf -s /etc /etc/hosts
Bash 等号区切り (例: --option=argument
)
cat >/tmp/demo-equals-separated.sh <<'EOF'
#!/bin/bash
for i in "$@"; do
case $i in
-e=*|--extension=*)
EXTENSION="${i#*=}"
shift # past argument=value
;;
-s=*|--searchpath=*)
SEARCHPATH="${i#*=}"
shift # past argument=value
;;
--default)
DEFAULT=YES
shift # past argument with no value
;;
-*|--*)
echo "Unknown option $i"
exit 1
;;
*)
;;
esac
done
echo "FILE EXTENSION = ${EXTENSION}"
echo "SEARCH PATH = ${SEARCHPATH}"
echo "DEFAULT = ${DEFAULT}"
echo "Number files in SEARCH PATH with EXTENSION:" $(ls -1 "${SEARCHPATH}"/*."${EXTENSION}" | wc -l)
if [[ -n $1 ]]; then
echo "Last line of file specified as non-opt/last argument:"
tail -1 $1
fi
EOF
chmod +x /tmp/demo-equals-separated.sh
/tmp/demo-equals-separated.sh -e=conf -s=/etc /etc/hosts
上記のブロックをコピーして貼り付けた出力
FILE EXTENSION = conf
SEARCH PATH = /etc
DEFAULT =
Number files in SEARCH PATH with EXTENSION: 14
Last line of file specified as non-opt/last argument:
#93.184.216.34 example.com
使用法
demo-equals-separated.sh -e=conf -s=/etc /etc/hosts
${i#*=}
「部分文字列の削除」をよりよく理解するには、このガイド`sed 's/[^=]*=//' <<< "$i"`
これは、不要なサブプロセスを呼び出す や、不要なサブプロセスを2 つ`echo "$i" | sed 's/[^=]*=//'`
呼び出すと機能的に同等です。
getopt[s] で bash を使用する
getopt(1) の制限 (比較的新しい古いgetopt
バージョン):
- 空の文字列の引数を処理できません
- 空白が埋め込まれた引数を処理できません
最新getopt
バージョンではこれらの制限はありません。詳細については、以下を参照してください。ドキュメント。
POSIX ゲトプット
さらに、POSIX シェルやその他のシェルでは、getopts
これらの制限がありません。単純な例を挙げてみましたgetopts
。
cat >/tmp/demo-getopts.sh <<'EOF'
#!/bin/sh
# A POSIX variable
OPTIND=1 # Reset in case getopts has been used previously in the shell.
# Initialize our own variables:
output_file=""
verbose=0
while getopts "h?vf:" opt; do
case "$opt" in
h|\?)
show_help
exit 0
;;
v) verbose=1
;;
f) output_file=$OPTARG
;;
esac
done
shift $((OPTIND-1))
[ "${1:-}" = "--" ] && shift
echo "verbose=$verbose, output_file='$output_file', Leftovers: $@"
EOF
chmod +x /tmp/demo-getopts.sh
/tmp/demo-getopts.sh -vf /etc/hosts foo bar
上記のブロックをコピーして貼り付けた出力
verbose=1, output_file='/etc/hosts', Leftovers: foo bar
使用法
demo-getopts.sh -vf /etc/hosts foo bar
の利点はgetopts
次のとおりです。
- より移植性が高く、 などの他のシェルでも動作します
dash
。 -vf filename
典型的な Unix の方法と同様に、複数の単一オプションを自動的に処理できます。
の欠点は、追加コードなしでは短いオプション ( 、ではなく)getopts
しか処理できないことです。-h
--help
そこにはgetopts チュートリアルこれは、すべての構文と変数の意味を説明しています。bash には、 もありhelp getopts
、参考になるかもしれません。