Pythonパラメータをシェルの配列に渡す

Pythonパラメータをシェルの配列に渡す

渡された引数を使用してサービスを生成するPythonスクリプトを実行するシェルスクリプトの作成中に、この状況が発生しました。サービスの作成時に変更される唯一の値であるため、サービス名と構成を配列に渡すことができるようにしたいので、残りのパラメータは同じままです。

以下のスクリプトを実行すると、各パラメータが1つのサービス呼び出しとして使用され、エラーは他のパラメータが欠落していることを示すため、5つの異なるサービス(エラーを含む)を生成します。以下のスクリプトで私は何を見逃していますか?この要件を満たすためのより良い方法はありますか?ありがとうございます!

job.shを起動

#!/bin/bash

#arguments
service=$1
config=$2
dockerv=$3
action=$4
file=$5

for addr in "$@"; do
 for service in "$@"; do
  for config in "$@"; do
    python /scripts/serviceStart.py -s "$service" -c "$config" -d "$dockerv" -t "$action" "$addr"
   done
 done
done

呼び出しスクリプト

/shellScripts/StartJobs.sh 720Test /720/config.xml 1080Test /1080/config.xml 5.6.0-1 Start 12.70.80.14 

720Test and 1080Test ---service 
/720/config.xml and 1080/config.xml ---config

/shellScripts/StartJobs.shを実行するたびに、単一のサービスと単一の構成値を取得する必要があります。上記には2つのサービスと2つの関連構成が指定されています。

シェルスクリプトはパラメータを使用してPythonスクリプトを実行し、同じIPで2つの異なるサービス(720用と1080用1つ)を起動すると予想しています。

 python /scripts/serviceStart.py -s 720Test -c /720/config.xml -d 5.6.0-1 -t Start 12.70.80.14
 python /scripts/serviceStart.py -s 1080Test -c /1080/config.xml -d 5.6.0-1 -t Start 12.70.80.14

また、これを試しましたが、エラーが返されず、サービスが生成されませんでした。

#!/bin/bash

args=()
while getopts ':d:t:' opt ; do 
case $opt in 
d) args+=( -d "$OPTARG" ) ;; 
t) args+=( -t "$OPTARG" ) ;;
?) echo "Invalid option $OPTARG" ;;
:) echo "Option $OPTARG needs an argument" ;;
esac
done

myarray[0]= $service
myarray[1]= $config

for ((i=0; i<${#service[@]}; i++) && (j=0; j<${#config[@]}; j++)) ; do
  echo $service
  echo $config
  python /scripts/serviceStart.py -s "${service[i]}" -c "${config[i]}" "${args[@]}" "$ip" 
sleep 5
done

答え1

あなたは次のように書きました:

サービス名と構成を配列に渡すことができるようにしたい

しかし、これは不可能です。実行されたプログラムはコマンドライン引数として単一のリスト/配列を取得するため、とにかくすべてのデータをそのリストに入れる必要があります。


あなたの例では、さまざまな種類のフィールドをインターリーブしたように見えます。

StartJobs.sh 720Test /720/config.xml 1080Test /1080/config.xml 5.6.0-1 Start 12.70.80.14

生成コマンド

python serviceStart.py -s 720Test -c /720/config.xml -d 5.6.0-1 -t Start 12.70.80.14
python serviceStart.py -s 1080Test -c /1080/config.xml -d 5.6.0-1 -t Start 12.70.80.14

つまり、ルールはリストの最後の3つの引数が各Python呼び出し(forおよび末尾のオプションではない引数)に使用され、リストの-d残り-tの部分は一度に2つの引数(forおよび-s-cです。

今、IMO、N処理中最後特にargsは非常にまれに聞こえます。 (そしてシェルで実行するのは厄介です。リストの先頭からのみアイテムを移動でき、最後のアイテムを表示することはできません。)最初は静的アイテムリストを使用することをお勧めします。より良い方法はgetoptsそれらに使用することです。だから:

#/bin/bash
while getopts ':d:t:a:' opt ; do 
case $opt in 
d) dockerv="$OPTARG" ;; 
t) action="$OPTARG" ;;
a) addr="$OPTARG" ;;
?) echo "Invalid option $OPTARG" ;;
:) echo "Option $OPTARG needs an argument" ;;
esac
done

shift "$((OPTIND - 1))"

if (( $# % 2 == 1 )); then
    echo >&2 "error: got odd number of args"
    exit 1
fi

while [[ "$#" -gt 1 ]]; do
    echo serviceStart.py -s "$1" -c "$2" -d "$dockerv" -t "$action" "$addr"
    shift 2 
done

それから

% bash startjobs.sh -d 5.6.0-1 -t Start -a 12.70.80.14 -- 720Test /720/config.xml 1080Test /1080/config.xml
serviceStart.py -s 720Test -c /720/config.xml -d 5.6.0-1 -t Start 12.70.80.14
serviceStart.py -s 1080Test -c /1080/config.xml -d 5.6.0-1 -t Start 12.70.80.14

(パラメータリストにさまざまな種類の値を配置するのが最善の方法であるか、それともこの区切り文字を持つ別々のパラメータを使用する方が良いか、または単に標準入力から名前とパスを読むのが良いかどうかわかりません1080Test:/1080/config.xmlが、おそらく自転車倉庫であるかもしれません。

関連情報