Olá, estou tentando ter
curl -v --request POST https://example.com --data-urlencode "username=usr]” --data-urlencode "password=[pass]”
passe a saída para o [TOKEN]
campo aqui:
curl -D - --request POST https://example.com --data-urlencode token=[TOKEN]
No entanto, não estou familiarizado com JSON, pois minha saída para o primeiro comando é
{
"token": "value_of_token"
}
Como eu pegaria apenas "value_of_token"
e faria com que fosse [TOKEN]
?
Responder1
Para obter mais eficiência apenas value_of_token
da saída do curl
comando, canalize a saída para um único sed
comando (editor de fluxo). Use a substituição de comando $()
para armazenar a saída em uma variável shell:
token=$(curl ... | sed -n '/ *"token": *"/ { s///; s/".*//; p; }')
Então você pode referenciar a variável token
como parâmetro para o segundo curl
comando:
curl ... token="$token"
Explicação do sed
comando:
sed -n '/ *"token" *: *"/ { s///; s/".*//; p; q; }'
-n
opção dizsed
paranãoimprimir cada linha de entrada/ *"token" *: *"/
aborda a linha que contém o valor. Este padrão (expressão regular) corresponde a todo o início da linha, até e incluindo a primeira aspa dupla que delimita o valor do token.{
inicie um bloco de comando que será aplicado à linha endereçada.s///;
um comando sed para excluir o que foi correspondido anteriormente (na parte do endereço). A linha ("espaço padrão") agora se parece com:value_of_token"
s/".*//
comando sed para excluir as aspas duplas restantes ("
) e tudo depois.p
comando sed para imprimir a linha atual (editada) ("espaço padrão" nased
terminologia).q
Saia imediatamente do script sed sem processar mais nenhuma entrada'}' finaliza o bloco de comando.
Por exemplo,
$ echo '
{
"token": "value_of_token"
}
' | sed -n '/ *"token" *: *"/ { s///; s/".*//; p; }'
value_of_token
$
Este método é muito mais eficiente do que juntar 4 outros comandos para obter o mesmo resultado. Este sed
comando pressupõe que não há caracteres de tabulação na entrada JSON. Se existirem guias, o sed
comando exigirá modificação.
Responder2
Primeiro, observe que tive que substituir o URL que você tem em seus comandos <URL>
porque o stackexchange pensou que eu estava enviando spam e não me deixou postar.
OK, você tem duas perguntas aqui:
1) Como você pega a saída de um comando e transforma-a em argumento de outro comando?
resposta: O método mais canônico seria usar a substituição de comando do shell, substituindo seu argumento no segundo comando por $( <first command> )
algo assim:
curl -D - --request POST <URL> --data-urlencode token=$( curl -v --request POST <URL> --data-urlencode "username=usr]” --data-urlencode "password=[pass]” )
No entanto, para fins de legibilidade, você realmente deve fazer isso em linhas separadas, salvando a saída do primeiro comando e reutilizando-a da seguinte forma:
token=$( curl -v --request POST <URL> --data-urlencode "username=usr]” --data-urlencode "password=[pass]” )
curl -D - --request POST <URL> --data-urlencode token="$token"
Além disso, para completar e porque você perguntou especificamente como "canalizar", você poderia usar o comando xargs em vez da substituição de comando do shell:
curl -v --request POST <URL> --data-urlencode "username=usr]” --data-urlencode "password=[pass]” | xargs "curl -D - --request POST <URL> --data-urlencode token="{}
No entanto, como você observou, a saída do primeiro comando não é exatamente o que você procura como token; portanto, as soluções acima não funcionariam como você espera, o que nos leva à sua próxima pergunta:
2) Como podemos isolar apenas “value_of_token” de toda a saída JSON?
Sem entrar em alguma API JSON, um simples pipeline de grep, head e cut deve resolver o problema:
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"
Observe que isso head -1
ocorre apenas no caso de haver várias linhas de token na saída; nesse caso, apenas a primeira é usada.
Você deve saber que esta não é uma solução muito robusta se esta aplicação for importante. Se for, você realmente deve verificar o código de retorno e fazer uma validação mais extensa da saída do primeiro comando curl para não obter resultados inesperados; mas isso exigiria um script maior e está além do escopo desta questão.