명령 출력에서 ​​값을 추출하고 해당 값을 후속 명령의 인수로 사용합니다.

명령 출력에서 ​​값을 추출하고 해당 값을 후속 명령의 인수로 사용합니다.

안녕하세요 갖고 싶어요

curl -v --request POST https://example.com --data-urlencode "username=usr]” --data-urlencode "password=[pass]”

출력을 [TOKEN]여기 필드에 전달합니다.

curl -D - --request POST https://example.com --data-urlencode token=[TOKEN]

하지만 첫 번째 명령의 출력이 다음과 같기 때문에 JSON에 익숙하지 않습니다.

{
    "token": "value_of_token"
}

어떻게 이것을 받아들이고 "value_of_token"실현할 수 있나요 [TOKEN]?

답변1

value_of_token명령 출력의 효율성을 극대화하려면 curl출력을 단일 sed(스트림 편집기) 명령으로 파이프하세요. 명령 대체를 사용하여 $()출력을 쉘 변수에 저장하십시오.

token=$(curl ... | sed -n '/ *"token": *"/ { s///; s/".*//; p; }')

token그런 다음 해당 변수를 두 번째 명령에 대한 매개변수로 참조할 수 있습니다 curl.

curl ... token="$token"

명령 설명 sed:

sed -n '/ *"token" *: *"/ { s///; s/".*//; p; q; }'
  • -n옵션이 sed말해준다아니요각 입력 줄을 인쇄합니다.

  • / *"token" *: *"/이 값이 포함된 행의 주소를 지정합니다. 이 패턴(정규 표현식)은 태그 값을 구분하는 첫 번째 큰따옴표까지 포함하여 줄의 전체 시작 부분과 일치합니다.

  • {지정된 줄에 적용될 명령 블록을 시작합니다.

  • s///;sed 명령은 이전에 일치한 내용(주소 부분에서)을 제거합니다. 이제 라인("패턴 공간")은 다음과 같습니다:value_of_token"

  • s/".*//sed 명령은 나머지 큰따옴표( ")와 그 뒤의 모든 항목을 제거합니다.

  • psed 명령은 현재(편집된) 줄( sed"패턴 공간"이라는 용어)을 인쇄합니다.

  • qsed 스크립트를 즉시 종료하고 더 이상 입력을 처리하지 않습니다.

  • '}'는 명령 블록을 종료합니다.

예를 들어,

$ echo '
{                          
    "token": "value_of_token"
}
' | sed -n '/ *"token" *: *"/ { s///; s/".*//; p; }'
value_of_token
$

이 방법은 동일한 결과를 얻기 위해 4개의 다른 명령을 파이프하는 것보다 훨씬 더 효율적입니다. 이 sed명령은 JSON 입력에 탭 문자가 없다고 가정합니다. 탭이 있으면 sed명령을 수정해야 합니다.

답변2

<URL>먼저, stackexchange는 내가 스팸을 보내고 게시를 허용하지 않을 것이라고 생각했기 때문에 명령에서 URL을 바꿔야 했습니다 .

좋습니다. 여기에 두 가지 질문이 있습니다.

1) 한 명령의 출력을 얻고 이를 다른 명령의 인수로 사용하는 방법은 무엇입니까?

답변: 가장 표준화된 방법은 쉘 명령 대체를 사용하여 두 번째 명령의 매개변수를 다음으로 바꾸는 것입니다 $( <first command> ).

curl -D - --request POST <URL> --data-urlencode token=$( curl -v --request POST <URL> --data-urlencode "username=usr]” --data-urlencode "password=[pass]” )

그러나 가독성을 위해 다음과 같이 첫 번째 명령의 출력을 저장하고 재사용하여 별도의 줄에서 이 작업을 수행해야 합니다.

token=$( curl -v --request POST <URL> --data-urlencode "username=usr]” --data-urlencode "password=[pass]” )
curl -D - --request POST <URL> --data-urlencode token="$token"

또한 완전성을 위해 "파이프" 방법을 구체적으로 요청했기 때문에 쉘의 명령 대체 대신 xargs 명령을 사용할 수 있습니다.

curl -v --request POST <URL> --data-urlencode "username=usr]” --data-urlencode "password=[pass]” | xargs "curl -D - --request POST <URL> --data-urlencode token="{}

그러나 지적한 대로 첫 번째 명령의 출력은 정확히 원하는 토큰이 아니므로 위의 솔루션은 예상대로 작동하지 않으므로 다음 질문이 발생합니다.

2) 전체 JSON 출력에서 ​​"value_of_token"을 어떻게 분리합니까?

일부 JSON API를 사용하지 않고도 간단한 grep, head 및 cut 파이프라인으로 작업을 수행할 수 있습니다.

token=$( curl -v --request POST <URL> --data-urlencode "username=usr]” --data-urlencode "password=[pass]” ) | grep '"token":' | head -1 | cut -d ':' -f 2 | cut -d '"' -f 2
curl -D - --request POST <URL> --data-urlencode token="$token"

이는 head -1출력에 여러 개의 마커 라인이 있는 경우이며, 이 경우 첫 번째 마커 라인만 사용됩니다.

이 애플리케이션이 중요하다면 이는 그다지 강력한 솔루션이 아니라는 점을 알아야 합니다. 그렇다면 첫 번째 컬 명령의 반환 코드를 확인하고 출력에 대한 보다 광범위한 유효성 검사를 수행하여 예상치 못한 결과를 얻지 않도록 해야 합니다. 하지만 그렇게 하려면 더 큰 스크립트가 필요하며 이 질문의 범위를 벗어납니다.

관련 정보