コマンドライン引数を名前と値のペアとしてシェルスクリプトに渡すことは可能ですか?
myscript action=build module=core
次に、私のスクリプトで、のような変数を取得して
$action
処理しますか?
$ 1 ....などを使用して変数を取得できることは知っていますが、ペアのような名前の値にはなりません。たとえそうであるとしても、スクリプトを使用する開発者は、同じ順序で変数を宣言する必要があります。私はそれを望んでいません。
これは私のために働いた:
for ARGUMENT in "$@"
do
KEY=$(echo $ARGUMENT | cut -f1 -d=)
KEY_LENGTH=${#KEY}
VALUE="${ARGUMENT:$KEY_LENGTH+1}"
export "$KEY"="$VALUE"
done
echo "STEPS = $STEPS"
echo "REPOSITORY_NAME = $REPOSITORY_NAME"
使用法
bash my_scripts.sh STEPS="ABC" REPOSITORY_NAME="stackexchange"
コンソールの結果:
STEPS = ABC
REPOSITORY_NAME = stackexchange
STEPSとREPOSITORY_NAMEは、スクリプトで使用する準備ができています。
引数の順序は関係ありません。
HTH
Bourneシェルには、めったに使用されないオプション' 'があり、コマンドラインで-k
指定された値を環境に自動的に配置します。name=value
もちろん、Bourne / Korn / POSIXシェルファミリー(bashを含む)はname=value
、コマンド名の前のアイテムに対してもこれを行います。
name1=value1 name2=value2 command name3=value3 -x name4=value4 abc
通常のPOSIXシェルの動作では、は環境内および環境内で、4つの引数を使用してcommand
呼び出されます。Bourne(およびKornとbash、ただしPOSIXではない)シェルオプションでは、、、、、および環境内で、2つの引数だけで呼び出されます。マニュアルページ(のように)は、同等のものについては言及していませんが、ボーンシェルとコーンシェルのように機能します。私はそれ(オプション)を真剣に使用したことはないと思います。name1
name2
-k
name1
name2
name3
name4
bash
man bash
-k
-k
command
スクリプト( )内から、環境変数がこのコマンド専用に指定されていることを確認する方法はありません。それらは、そのスクリプトの環境における単なる環境変数です。
これは、あなたが求めているものに私が知っている最も近いアプローチです。Cシェルファミリーに相当するものはないと思います。name=value
コマンドラインのペアから変数を設定する他の引数パーサーを知りません。
かなり重要な注意事項がいくつかあります(単純な値の場合は比較的簡単ですが、シェルのメタ文字を含む値を処理するのは困難です)。
case $1 in
(*=*) eval $1;;
esac
これはCシェルファミリではありません。eval
シェルの割り当てを効果的に行います。
arg=name1=value1
echo $name1
eval $arg
echo $name1
env action=build module=core myscript
あなたはtcshを使用していると言いました。Bourneベースのシェルの場合、「env」を削除できますが、そのままにしておくのは無害です。これは、の実装に使用されるシェルではなく、コマンドを実行するシェルに適用されることに注意してくださいmyscript
。
特にname=valueのペアをコマンド名に従わせたい場合は、内部でいくつかの作業を行う必要がありますmyscript
。
これはかなり古い質問ですが、それでも有効です。Cookieカットの解決策は見つかりませんでした。上記の答えを組み合わせました。私のニーズに合わせて、このソリューションを作成しました。これwhite space
は、引数の値でも機能します。
これを名前を付けて保存argparse.sh
#!/bin/bash
: ${1?
'Usage:
$0 --<key1>="<val1a> <val1b>" [ --<key2>="<val2a> <val2b>" | --<key3>="<val3>" ]'
}
declare -A args
while [[ "$#" > "0" ]]; do
case "$1" in
(*=*)
_key="${1%%=*}" && _key="${_key/--/}" && _val="${1#*=}"
args[${_key}]="${_val}"
(>&2 echo -e "key:val => ${_key}:${_val}")
;;
esac
shift
done
(>&2 echo -e "Total args: ${#args[@]}; Options: ${args[@]}")
## This additional can check for specific key
[[ -n "${args['path']+1}" ]] && (>&2 echo -e "key: 'path' exists") || (>&2 echo -e "key: 'path' does NOT exists");
@例:スクリプトへの引数にはオプションのプレフィックスを付けることができることに注意してください--
./argparse.sh --x="blah"
./argparse.sh --x="blah" --yy="qwert bye"
./argparse.sh x="blah" yy="qwert bye"
このスクリプトのいくつかの興味深いユースケース:
./argparse.sh --path="$(ls -1)"
./argparse.sh --path="$(ls -d -1 "$PWD"/**)"
上記の要点として作成されたスクリプト、参照:argparse.sh
ジョナサンの答えを拡張すると、これは私にとってうまく機能しました:
#!/bin/bash
if [ "$#" -eq "0" ]; then
echo "Error! Usage: Remind me how this works again ..."
exit 1
fi
while [[ "$#" > "0" ]]
do
case $1 in
(*=*) eval $1;;
esac
shift
done