쉘 스크립트의 변수를 통해 매개변수를 전달할 때 컬이 작동하지 않습니다.

쉘 스크립트의 변수를 통해 매개변수를 전달할 때 컬이 작동하지 않습니다.

실행하려면 콘솔에 다음 명령을 직접 입력하세요.

[root@server user]# curl -d 'parameter=170.22.16.14 192.10.2.24 - - [01/Jan/1900:00:00:00 -0300] "GET  /files/notes.txt HTTP/1.1" 200 112061 "-" "Java/1.8.0.160"' -H 'Content-Type: application/x-www-form-urlencoded' -X POST http://192.138.1.10:8080/system/add

반면에 bash 스크립트가 있습니다 addinfo.sh.

#!/bin/bash

tail -n0 -F info.txt | while read LINE; do
    ins="curl -d 'parameter=$LINE' -H 'Content-Type: application/x-www-form-urlencoded' -X POST http://192.138.1.10:8080/system/add"
    echo $ins
    $ins
done

그런 다음 다음 echo 명령을 실행하면 출력이 keep으로 표시됩니다.

[root@server user]# echo '170.22.16.14 192.10.2.24 - - [01/Jan/1900:00:00:00 -0300] "GET  /files/notes.txt HTTP/1.1" 200 112061 "-" "Java/1.8.0.160"' >> info.txt
[root@server user]# curl -d 'parameter=170.22.16.14 192.10.2.24 - - [01/Jan/1900:00:00:00 -0300] "GET  /files/notes.txt HTTP/1.1" 200 112061 "-" "Java/1.8.0.160"' -H 'Content-Type: application/x-www-form-urlencoded' -X POST http://192.138.1.10:8080/system/add
curl: option -: is unknown
curl: try 'curl --help' or 'curl --manual' for more information

HTTP 요청이 실행되지 않았습니다. 다음 입력 데이터는 변경할 수 없습니다.

170.22.16.14 192.10.2.24 - - [01/Jan/1900:00:00:00 -0300] "GET  /files/notes.txt HTTP/1.1" 200 112061 "-" "Java/1.8.0.160"

그렇다면 Bash 스크립트를 수정하려면 어떻게 해야 합니까?

답변1

ins="curl -d 'parameter=$LINE' -H 'Content-Type: application/x-www-form-urlencoded' -X POST http://192.138.1.10:8080/system/add"

변수에 입력하는 것은 쉘 구문입니다. 이는 쉘이 구문 분석할 쉘 명령줄에(대화식으로 또는 스크립트로) 입력하는 명령 형식입니다.

$ins

그러나 이는 쉘 구문의 변수 내용을 구문 분석하지 않습니다. 대신 토큰화와 와일드카드를 값에 적용하고 결과 필드를 명령 이름과 인수로 사용합니다. 이는 따옴표, 연산자(리디렉션 포함) 또는 확장(달러 기호 또는 백틱 포함)과 같은 구문 요소를 처리하는 것과 다릅니다.

여기서는 명령 이름과 매개변수 curl,,,, 등이 생성됩니다.-d 'parameter=170.22.16.14192.10.2.24--

거기에 있는 어려운 인용문을 참고하세요. 이는 쉘 명령을 실행할 때 얻는 것과 동일한 결과입니다.

curl -d "'parameter=170.22.16.14" 192.10.2.24 - - etc.

원칙의 근본적인 차이점은 변수에 다음이 포함되어야 한다는 것입니다.데이터, 데이터는 코드로 구문 분석되지 않습니다. 따옴표를 사용할 때 이와 같이 작동하기를 원할 수도 있지만 이는 예를 들어 모든 명령 대체가반품예를 들어, 명령줄 인수나 파일 이름에 실행 및 이와 유사한 문자열이 나타날 수 있습니다. 합리적인 방법으로 임의의 문자열을 처리하는 것은 불가능합니다.

정확하게 말하면 데이터에 코드를 넣지 말고 직접 명령을 실행하세요.

tail -n0 -F info.txt | while read LINE; do
    curl -d "parameter=$LINE" -H 'Content-Type: application/x-www-form-urlencoded' -X POST http://192.138.1.10:8080/system/add
done

또는 원하는 경우 먼저 명령을 함수에 저장하세요.

f() {
    curl -d "parameter=$1" -H 'Content-Type: application/x-www-form-urlencoded' -X POST http://192.138.1.10:8080/system/add
}
tail -n0 -F info.txt | while read LINE; do
    f "$LINE"
done

실행 중인 명령을 인쇄하려면 set -x셸을 사용하여 실제로 실행된 내용을 인쇄할 수 있습니다. (Bash는 쉘 입력으로 다시 사용하기에 적합한 명확한 형식으로 이 작업을 수행합니다. 다른 형식은 모호한 출력을 생성할 수 있습니다.)

위의 함수를 수정하세요:

f() (
    set -x
    curl -d "parameter=$1" -H 'Content-Type: application/x-www-form-urlencoded' -X POST http://192.138.1.10:8080/system/add
)

또는 전체 명령을 배열에 저장하고 인쇄한 다음 실행할 수 있습니다. (그러나 이는 모호한 출력을 제공합니다):

f() {
    cmd=(curl -d "parameter=$1" -H 'Content-Type: application/x-www-form-urlencoded' -X POST http://192.138.1.10:8080/system/add)
    printf "%s " "${cmd[@]}"
    echo
    "${cmd[@]}"
}

바라보다:변수에 저장된 명령을 어떻게 실행할 수 있나요?

관련 정보