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루프의 네 줄을 하나로 바꿀 수 있습니다.while read ...

readarray -t ip_list < "${ip_file}"

readarray방법은 한 줄에 불과하며 설명이 매우 간단합니다. 반면 루프는 값을 배열에 저장하기 전에 변경할 수 있는 while read ...기회를 제공합니다 . ${ip_line}선행/후행 공백 문자를 제거하거나 줄이 비어 있는지 등을 테스트할 수도 있습니다.

값을 배열에 저장하는 명령문은 push(array, value)Bash에서 작업을 구현하는 방법이며 push()가 없습니다. 기본적으로 배열의 현재 길이를 가져오고 해당 숫자를 다음 요소의 인덱스로 사용하여 새 값을 저장합니다.

매개변수의 길이를 짧고 이해하기 쉽게 유지하기 위해 URL, 이메일 주소, API 키를 변수에 넣는데, curl그건 개인적으로 선호하는 방식입니다.

JSON blob(데이터 구조)의 경우 shell 을 사용하여 조립하는 것이 훨씬 쉽다는 것을 알았습니다 Here Document. 작은따옴표 및 큰따옴표 문자는 문자열에서 제거되지 않으며 여러 줄 들여쓰기를 사용하여 JSON을 변경해야 하는 사람들이 읽을 수 있도록 만들 수 있습니다. 여기서 문서의 주변 구조를 다루는 것은 $(cat - <<EOJSON혼란 JSON )스러울 수 있지만 주석 줄이 도움이 될 수 있습니다. 제 생각에는 스크립트를 사용하는 다음 코더가 JSON을 이해하기 더 쉽다면 그만한 가치가 있다고 생각합니다. 또는 JSON을 모두 하나의 긴 줄에 넣을 수도 있습니다. 여기에 있는 문서는 작은따옴표 및 큰따옴표 문자를 사용하여 플레이하는 데 필요한 게임을 여전히 줄여줍니다.

나는 쉘 변수로 구축된 특정 요소 주위에 따옴표를 원하는 다른 복잡한 문자열에 대해 여기 문서를 사용합니다. jq내가 생각하는 것은 JMESPath 쿼리와 MySQL 명령입니다.

나는 스크립트에서 문서를 들여쓰지 않는 경향이 있습니다. 대부분의 셸에서 줄 끝( EOJSON이 경우)을 들여쓰기하려면 탭을 사용해야 하는데, 탭을 공백으로 쉽게 다시 쓸 수 있으므로 여기에서 문서가 깨집니다. JSON 줄을 들여쓰지만 닫는 줄을 들여쓰지 않는 것은 줄을 들여쓰지 않는 것보다 더 혼란스러울 수 있으므로 주석으로 설명하세요. 이것은 단지 내 개인적인 의견입니다.

관련 정보