[解決済み] Bashでコマンドライン引数を解析するには?
2022-03-14 09:21:19
質問
例えば、次のような行で呼び出されるスクリプトがあるとします。
./myscript -vfd ./foo/bar/someFile -o /fizz/someOtherFile
とか、これとか。
./myscript -v -f -d -o /fizz/someOtherFile ./foo/bar/someFile
これを解析して、それぞれの場合(またはその組み合わせ)には、どのような方法があるのでしょうか。
$v
,
$f
および
$d
はすべて
true
と
$outFile
と同じになります。
/fizz/someOtherFile
?
解決方法は?
バッシュ スペースセパレート(例.
--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 Equals-Separated(例.
--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#*=}
でquot;Substring Removal"を検索してください。
このガイド
. と機能的に同等です。
`sed 's/[^=]*=//' <<< "$i"`
を呼び出すか、不要なサブプロセスを呼び出す
`echo "$i" | sed 's/[^=]*=//'`
を呼び出すものです。
に
のような不要なサブプロセスです。
getopt[s]でbashを使う。
getopt(1) の制限事項 (古いもの、比較的新しいもの)
getopt
のバージョン)。
- 空文字列の引数は扱えません
- 空白文字が埋め込まれた引数を扱えない
より新しい
getopt
のバージョンでは、これらの制限はありません。詳しくは、これらの
ドキュメント
.
POSIX getopts
さらに、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
というのがありますが、これは参考になるかもしれません。
関連
-
[解決済み] 絶対パスと論理パスの違い
-
[解決済み] Bashスクリプトのソースディレクトリをスクリプト自体から取得するにはどうすればよいですか?
-
[解決済み] Bashシェルスクリプトでディレクトリが存在するかどうかを確認するにはどうすればよいですか?
-
[解決済み] Bashで通常のファイルが存在しないかどうかを判断する方法を教えてください。
-
[解決済み] Bashで文字列変数を連結する方法
-
[解決済み] Node.jsのプログラムにコマンドライン引数を渡すにはどうしたらいいですか?
-
[解決済み] Bashで文字列をデリミターで分割するには?
-
[解決済み] MySQLでコマンドラインを使用してSQLファイルをインポートするにはどうすればよいですか?
-
[解決済み] Bashでコマンドの出力に変数を設定するにはどうすればよいですか?
-
[解決済み] リファレンス - このシンボルはPHPで何を意味するのですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】bashでjsonファイルを解析するために、jqの出力にあるダブルクオートを削除する方法は?
-
[解決済み】shでJenkinsのステージから他のステージに変数を渡す
-
[解決済み】ZIPエラー - 何もできない
-
[解決済み】firebase-tools "-bash: firebase: command not found".
-
[解決済み] zip警告 - 名前が一致しない
-
[解決済み] Bash/Terminalで複数行の環境変数を書き出す方法 例: RSA秘密鍵
-
[解決済み] bashでjsonファイルを解析するためにjqの出力からダブルクオートを削除する方法は?
-
[解決済み] シンタックスエラー」が発生しました。"(" unexpected' (expecting "done") [duplicate]".
-
[解決済み] bashスクリプトでfindコマンドを使用する
-
[解決済み] Bashスクリプトの'''抜け'''がある] [クローズド]