안녕하세요.
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 명령을 사용하여 나머지 큰따옴표("
)와 그 이후의 모든 항목을 삭제합니다.p
현재(편집된) 줄(sed
용어로는 "패턴 공간")을 인쇄하는 sed 명령입니다.q
더 이상 입력을 처리하지 않고 sed 스크립트를 즉시 종료합니다.'}' 명령 블록을 종료합니다.
예를 들어,
$ 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 출력에서 "token_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
출력에 여러 개의 토큰 라인이 있는 경우를 대비하여 첫 번째 토큰 라인만 사용됩니다 .
이 애플리케이션이 중요하다면 이는 매우 강력한 솔루션이 아니라는 점을 알아야 합니다. 그렇다면 반환 코드를 확인하고 첫 번째 컬 명령의 출력에 대한 보다 광범위한 유효성 검사를 수행하여 예상치 못한 결과가 발생하지 않도록 해야 합니다. 하지만 그러려면 더 큰 스크립트가 필요하며 이 질문의 범위를 벗어납니다.