Bashスクリプトがインポートしたテキストファイルデータを使用してコード全体を実行しないのはなぜですか?

Bashスクリプトがインポートしたテキストファイルデータを使用してコード全体を実行しないのはなぜですか?

Cloudflare WAFに保存されているIPアドレスリストのテキストファイルをホワイトリストに追加したいと思います。これを行うには、bashスクリプトを含む次のCloudflare API4カールを使用します。

この Cloudflare API スクリプトでは、インポートした IP アドレスデータを使用できません。デバッグ時に「無効なIPアドレス」メッセージが表示されます(Cloudflare側)。

別のテキストファイルからこのスクリプトのIPアドレスデータをロードしたいと思います。

ファイルからデータをインポートするには?

私のローカルに保存されているファイルには、次の形式のデータが含まれています。

123.123.123.124 
123.123.123.57 
123.123.123.91

これはCloudflare IPホワイトリストスクリプトです。

#!/bin/bash
    
input="/var/download/ip.txt"
while IFS= read -r line
do
  echo "$line"
done < "$input"
    
    for i in "${line[@]}"
    do
       : 
       # do whatever on $i
        echo $i
        curl -X POST "https://api.cloudflare.com/client/v4/user/firewall/access_rules/rules" \
             -H "X-Auth-Email: myemail" \
             -H "X-Auth-Key: globle API key" \
             -H "Content-Type: application/json" \
             --data '{"mode":"whitelist","configuration":{"target":"ip","value":"'$i'"},"notes":"Google Bot IP"}'

    done

答え1

このスクリプトを実装した方法は次のとおりです。吹く(元の質問に基づいて)。あなたの例といくつかの他の部分がありますが、これを提案する理由を説明します。

#!/bin/bash

# the IP addresses are in a file, one per line
ip_file='/var/download/ip.txt'

# get the IP addresses from the file into an array
while read -r ip_line
do
  ip_list[${#ip_list[@]}]="${ip_line}"
done < "${ip_file}"

# was the file empty?
[[ ${#ip_list[@]} -lt 1 ]] && {
  echo "$0: Error, no ip addresses in ${ip_file}" >&2
  exit 1
}

# parameterize the unchanging parts of the curl commands
url='https://api.cloudflare.com/client/v4/user/firewall/access_rules/rules'
my_email='my-email@my-domain'
api_key='1234567890abcdef'

# loop through the list of IPs
for ip_addr in "${ip_list[@]}"
do
  # use a here document to put the IP into the json blob
  # (the here document is not indented)
  whitelist_json=$(cat - <<EOJSON
{
  "mode":"whitelist",
  "configuration": {
    "target": "ip",
    "value": "${ip_addr}"
  },
  "notes":"Google Bot IP"
}
EOJSON
)

  # tell my user what I'm doing
  echo "Submitting whitelist for IP ${ip_addr}"

  # the curl command to submit the address
  echo curl \
  -X POST "${url}" \
  -H "Content-Type: application/json" \
  -H "X-Auth-Email: ${my_email}" \
  -H "X-Auth-Key: ${api_key}" \
  --data "${whitelist_json}"
done

ファイルに対して実行し、正しいコマンド引数が生成されていることを確認したら、前のechoエントリを削除します。curlip.txt

ファイルにUnix / Linux行末がある場合は、ip.txtループの4行を1つに置き換えることができます。while read ...

readarray -t ip_list < "${ip_file}"

このreadarray方法は一行にすぎず、説明は非常に簡単です。一方、ループは値を配列に保存する前に変更するwhile read ...機会を提供します。${ip_line}先行/末尾の空白文字を削除したり、行が空であるかどうかをテストすることもできます。

値を配列に格納するステートメントはpush(array, value)Bash でアクションを実装する方法であり、 push() はありません。デフォルトでは、配列の現在の長さを取得し、その数値を次の要素のインデックスとして使用して新しい値を保存します。

パラメータの長さを短く理解しやすくするために、URL、Eメールアドレス、APIキーを変数に入れます。curlこれは個人的に好む方法です。

JSON blob(データ構造)では、シェルを使用して組み立てるのがはるかに簡単であることがわかりましたHere Document。一重引用符と二重引用符文字は文字列から削除されず、複数行のインデントを使用してJSONを変更する必要がある人が読みやすいようにすることができます。ここで文書の周辺構造を扱うのは$(cat - <<EOJSON混乱JSON )するかもしれませんが、コメント行が役に立つかもしれません。私の考えでは、スクリプトを使用している次のコーダーがJSONを理解するのがより簡単であれば、それは価値があると思います。あるいは、JSONをすべて1つの長い行に入れることもできます。ここにあるドキュメントは、一重引用符と二重引用符文字を使用して再生するために必要なゲームを引き続き削減します。

私はシェル変数で構築された特定の要素の周りに引用符を付けたい他の複雑な文字列のためにここでドキュメントを使用します。jq私が考えるのはJMESPathクエリとMySQLコマンドです。

私はスクリプトから文書をインデントしない傾向があります。ほとんどのシェルで行末(EOJSONこの場合)をインデントするには、タブを使用する必要があります。タブを空白に簡単に書き換えることができるため、ここで文書が壊れます。 JSON行をインデントするが閉じる行をインデントしないことは、行をインデントしないよりも混乱する可能性があるため、コメントとして説明してください。これは私の個人的な意見です。

関連情報