Bash에서 동적 결과를 갖는 동적 변수

Bash에서 동적 결과를 갖는 동적 변수

dubdub_count=3

for (( i=1; i<=${dubdub_count}; i++ )); do
  my_apps --ammount=${dubdub_count}
done

프로그램은 IP 주소 예제 결과를 반환합니다.

app1=10.10.10.1
app2=10.10.10.2
app3=10.10.10.3

이러한 IP 주소는 다른 서비스에 사용됩니다. 아래와 같이 apiserver 명령을 실행하기 위해 apiserver.sh bash 스크립트를 만들고 있습니다.

/usr/local/bin/apiserver --dubdub=http://${app1},http://${app2},http://{app3} --master

내 apiserver.sh가 my_apps 결과의 동적 결과를 추가할 수 있기를 원합니다.

dubdub_count=3스크립트 를 변경하면 dubdub_count=4 다음과 같이 실행될 수 있어야 합니다.

/usr/local/bin/apiserver --dubdub=http://10.10.10.1:8080,http://10.10.10.2:8080,http://10.10.10.3,http://10.10.10.4 --master

dubdub_count=3스크립트 를 변경하면 dubdub_count=5 다음과 같이 실행될 수 있어야 합니다.

/usr/local/bin/apiserver --dubdub=http://10.10.10.1:8080,http://10.10.10.2:8080,http://10.10.10.3:8080,http://10.10.10.4:8080,http://10.10.10.5:8080 --master

요약 질문은 my_app 결과를 매개변수에 자동으로 추가하는 방법입니다 --dubdub. my_app이 6개의 IP 주소를 반환하면 my --dubdub도 6개의 IP 주소를 얻습니다. bash 스크립트를 수동으로 편집할 필요가 없습니다.

dynamic var in bashstackoverflow에서 as 키워드를 읽었지만 여전히 최상의 솔루션을 찾을 수 없습니다 . my_apps 개발자에게 결과 방법을 변경하라고 조언해야 합니까?

답변1

을 추가하여 http://사용한 :8080다음 sed함께 paste -sd,모아서 쉼표로 구분할 수 있습니다.

urllist=$(
  for ... done \
  | cut -d= -f2 \
  | sed 's#.*#http://&:8080#' \
  | paste -sd, -
) # output: http://10.10.10.1:8080,http://10.10.10.2:8080,http://10.10.10.3:8080
/usr/local/bin/apiserver --dubdub="$urllist" --master

cut또는 하나의 명령으로 를 실행 sed하고 함께 paste수행합니다 awk.

urllist=$(
  for ... done \
  | awk -F= 'NR>1{printf ","};{printf "http://"$2":8080"}'
) # output: http://10.10.10.1:8080,http://10.10.10.2:8080,http://10.10.10.3:8080
/usr/local/bin/apiserver --dubdub="$iplist" --master

답변2

다음으로 시작하세요:

$ seq -f "http://10.10.10.%g:8080" 1 3
http://10.10.10.1:8080
http://10.10.10.2:8080
http://10.10.10.3:8080

그런 다음 이를 함수로 바꿀 수 있습니다.

$ ddcount() { seq -f "http://10.10.10.%g:8080" "$@" ; }
$ ddcount 5 7
http://10.10.10.5:8080
http://10.10.10.6:8080
http://10.10.10.7:8080

(참고: 이는 모든 인수를 명령에 전달하기 때문에 seqFIRST 인수는 선택 사항이며 기본값은 1입니다. seq 3seq 1 3, ddcount 3와 동일합니다 ddcount 1 3. 필요한 경우 증분을 지정할 수도 있습니다. man seq세부 정보 보기)

이것을 다른 함수와 결합하여 구분 기호(예: 쉼표)를 사용하여 매개변수를 연결합니다.

$ join_by() { local d=$1; shift; printf '%s' "$1"; shift; printf '%s' "${@/#/$d}"; }

이는 Perl 함수를 join()모델로 했지만 명령과 충돌 join_by하지 않도록 이름이 지정되었습니다. join첫 번째 매개변수는 구분 기호입니다. 나머지 매개변수는 연결할 데이터입니다.

$ join_by , $(ddcount 1 3)
http://10.10.10.1:8080,http://10.10.10.2:8080,http://10.10.10.3:8080

참고: $(ddcount 1 3)함수 호출에 큰따옴표를 사용하지 마십시오.생각하다반환되는 문자열은 하나의 긴 문자열로 처리되지 않고 여러 항목으로 토큰화됩니다. 위 명령의 출력을 비교하여 join_by , "$(ddcount 1 3)"차이점을 확인하세요.

마지막으로 모두 정리하면 다음과 같습니다.

start=1; stop=3
/usr/local/bin/apiserver --dubdub="$(join_by , $(ddcount "$start" "$stop"))" --master

또는

dd="$(join_by , $(ddcount "$start" "$stop"))"
/usr/local/bin/apiserver --dubdub="$dd" --master

답변3

첫 번째 루프를 자체 스크립트나 호출된 셸 함수에 넣을 수 있다고 가정합니다 (또는 아래 호출 my_apps_loop에 삽입할 수 있습니다 ).my_apps_loop

#!/bin/bash

urls=()

# Create URLs
while IFS='=' read -r app ip; do
    urls+=( "http://$ip:8080" )
done < <(my_apps_loop)

(
    IFS=','

    # Call apiserver with generated URLs
    /usr/local/bin/apiserver --dubdub="${urls[*]}" --master
)

이는 into의 일부 출력 my_apps_loop(등을 사용하여 행을 출력함 app1=...)과 into 다음에 오는 문자열을 반복합니다.appN$app=$ip

읽은 각 줄에 대해 비트 는 해당 비트로 시작하는 $ip문자열로 접미사가 붙고 배열에 삽입됩니다 .http://:8080urls

최종 서브셸 호출 apiserver. 이 --dubdub옵션은 urls배열에서 값을 가져와 배열의 값을 쉼표로 구분된 문자열로 연결합니다.

관련 정보