9

コマンドライン引数を名前と値のペアとしてシェルスクリプトに渡すことは可能ですか?

myscript action=build module=core

次に、私のスクリプトで、のような変数を取得して $action処理しますか?

$ 1 ....などを使用して変数を取得できることは知っていますが、ペアのような名前の値にはなりません。たとえそうであるとしても、スクリプトを使用する開発者は、同じ順序で変数を宣言する必要があります。私はそれを望んでいません。

4

5 に答える 5

14

これは私のために働いた:

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

STEPSREPOSITORY_NAMEは、スクリプトで使用する準備ができています。

引数の順序は関係ありません。

HTH

于 2017-03-24T20:27:42.253 に答える
4

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つの引数だけで呼び出されます。マニュアルページ(のように)は、同等のものについては言及していませんが、ボーンシェルとコーンシェルのように機能します。私はそれ(オプション)を真剣に使用したことはないと思います。name1name2-kname1name2name3name4bashman bash-k-k

commandスクリプト( )内から、環境変数がこのコマンド専用に指定されていることを確認する方法はありません。それらは、そのスクリプトの環境における単なる環境変数です。

これは、あなたが求めているものに私が知っている最も近いアプローチです。Cシェルファミリーに相当するものはないと思います。name=valueコマンドラインのペアから変数を設定する他の引数パーサーを知りません。


かなり重要な注意事項がいくつかあります(単純な値の場合は比較的簡単ですが、シェルのメタ文字を含む値を処理するのは困難です)。

case $1 in
(*=*) eval $1;;
esac

これはCシェルファミリではありません。evalシェルの割り当てを効果的に行います。

arg=name1=value1
echo $name1
eval $arg
echo $name1
于 2011-03-31T14:33:25.270 に答える
1
env action=build module=core myscript

あなたはtcshを使用していると言いました。Bourneベースのシェルの場合、「env」を削除できますが、そのままにしておくのは無害です。これは、の実装に使用されるシェルではなく、コマンドを実行するシェルに適用されることに注意してくださいmyscript

特にname=valueのペアをコマンド名に従わせたい場合は、内部でいくつかの作業を行う必要がありますmyscript

于 2011-07-30T19:59:03.453 に答える
1

これはかなり古い質問ですが、それでも有効です。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

于 2020-08-09T20:36:01.740 に答える
0

ジョナサンの答えを拡張すると、これは私にとってうまく機能しました:

#!/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
于 2016-02-03T06:14:00.353 に答える