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://使用し:8080sed一緒に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または、1つのコマンドでを実行し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 3つまりseq 1 3ddcount 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)関数呼び出しに二重引用符を使用しないでください。考える返される文字列は、1つの長い文字列として扱われず、複数の項目にトークン化されます。上記のコマンドの出力を比較して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配列から値を取得し、配列の値をカンマ区切り文字列に連結します。

関連情報