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용 하나)를 시작할 것으로 예상합니다.

 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

즉, 규칙은 목록의 마지막 세 인수가 각 Python 호출( for 및 끝에 있는 옵션이 아닌 인수)에 사용되고 -d목록 -t의 나머지 부분은 한 번에 두 개의 인수( 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. 하지만 아마도 자전거 창고일 것입니다. 가장 간단한 구현은 실제 소스 데이터의 형식에 따라 달라질 수 있으므로 가장 기분이 좋은 작업을 수행하면 됩니다.

관련 정보