como faço para validar um arquvo JSON? [RESOLVIDO]

1. como faço para validar um arquvo JSON? [RESOLVIDO]

Cristiano Martins Santana
cristiano-dev

(usa Ubuntu)

Enviado em 13/04/2020 - 17:38h

como faço para validar um arquvo JSON?

exemplo de uma entra validada com jq:

echo '{"chave": "valor"}' | jq -e . ; echo $?

Isso retornar o codigo de erro 0 (zero), e a entrada formatada.

exemplo de uma entra invalidada também usando jq:

echo 'entradainvalida' | jq . ; echo $?

A saida disso é:
"parse error: Invalid numeric literal at line 2, column 0"
E codigo de erro 4, já que a entrada é invalida.

Entretanto, a entrada invalida abaixo não gera nem um erro.

echo '{"chave": "val' | jq . ; echo $?


se eu fizer:


echo '{"chave": "val' | jq . > meu_arquivo_de_configuração

vai apagar tudo.

Sendo assim, como faço para validar?



  


2. MELHOR RESPOSTA

Rogerio
RogerDez

(usa Outra)

Enviado em 13/04/2020 - 18:03h

no meu jq, ele retorna erro para aquele teste que vc falou.
[~]$ echo '{"chave": "val' | jq . ; echo $?
parse error: Unfinished string at EOF at line 2, column 0
4


man jq
-e / --exit-status:

Sets the exit status of jq to 0 if the last output values was nei‐
ther false nor null, 1 if the last output value was either false or
null, or 4 if no valid result was ever produced. Normally jq exits
with 2 if there was any usage problem or system error, 3 if there
was a jq program compile error, or 0 if the jq program ran.

Another way to set the exit status is with the halt_error builtin
function


o jq sempre vai retornar sair com sinal >0 se houver erro. o jq -e é somente
para ele analisar qual tipo de erro ocorreu e informar o usuário.
mas eu tb faço teste de vaidação com o jq -e

no caso, com esse redirecionamento '>' é controlado pela shell.
a primeira coisa que a shell faz antes de executar a linha de comando
é verificar se exite redirecionamento de output.
então apesar do jq sair com erro, a shell já abriu o redirecionamento para o
arquivo especificado e fica esperando o saida stdout do jq, mas se ele
ele faz erro, a mensagem de erro vai para stderr, ou seja, o redirecionamento
da shell vai resultar em um arquivo vazio.

eu faria o seguinte:

jsonstr='{"chave": "val'

if jq -e <<<"$jsonstr" &>/dev/null; then
jq <<<"$jsonstr" > meu_arquivo_de_configuração
else
echo 'erro com json' 1>&2
#exit 1
fi

testaria a saida do jq diretamente ao invés de usar a variável $?
vc só precisa testar $? se quiser verificar qual o tipo de erro ocorrido,
mas nesse caso qq erro é o suficiente para nos
como é para testes, mandamos o stderr e o stdout para /dev/null com &>/dev/null
somente se passar este teste, em seguida exececuta o jq novamente com a redireção do stdout para o arquivo
se for para desdobrar o json inteiro, não é necessário o ponto '.' no comando do jq.

já que estamos usando redirecionamento, apresento o 'here string'
então se vc tiver uma variável com o json ou o próprio texto do json, pode usar uma 'here string' ao invés de usar o cat
here string
<<< '{ "key":"value" }'
ele é os três <<<
vc lê assim, jq recebe de ...
ao invés de cat manda para jq..

e depois o redirecionamento que vc conhece, o > para sobrescrever o arquivo.
ficaria jq recebe de 'jsonstr' e manda para arquivo_de_configuração

ou para capturar a mensagem de erro do jq, que é melhor que uma mensagem de erro padrão:

jsonstr='{"chave": "val'

if jq -e <<<"$jsonstr" >/dev/null; then
jq <<<"$jsonstr" > meu_arquivo_de_configuração
fi


aqui estamos redirecionando somente o stdout ( não precisa especificar o 1) no caso do teste. se houver erro, o jq vai mandar a mensagem por stderr e não vai passar no teste. confiamos que o jq gera mensagens de erro boas para o usuário fazer a verificação.

abraço


3. Re: como faço para validar um arquvo JSON? [RESOLVIDO]

Cristiano Martins Santana
cristiano-dev

(usa Ubuntu)

Enviado em 13/04/2020 - 19:18h

RogerDez escreveu:

no meu jq, ele retorna erro para aquele teste que vc falou.
[~]$ echo '{"chave": "val' | jq . ; echo $?
parse error: Unfinished string at EOF at line 2, column 0
4


man jq
-e / --exit-status:

Sets the exit status of jq to 0 if the last output values was nei&#8208;
ther false nor null, 1 if the last output value was either false or
null, or 4 if no valid result was ever produced. Normally jq exits
with 2 if there was any usage problem or system error, 3 if there
was a jq program compile error, or 0 if the jq program ran.

Another way to set the exit status is with the halt_error builtin
function


o jq sempre vai retornar sair com sinal >0 se houver erro. o jq -e é somente
para ele analisar qual tipo de erro ocorreu e informar o usuário.
mas eu tb faço teste de vaidação com o jq -e

no caso, com esse redirecionamento '>' é controlado pela shell.
a primeira coisa que a shell faz antes de executar a linha de comando
é verificar se exite redirecionamento de output.
então apesar do jq sair com erro, a shell já abriu o redirecionamento para o
arquivo especificado e fica esperando o saida stdout do jq, mas se ele
ele faz erro, a mensagem de erro vai para stderr, ou seja, o redirecionamento
da shell vai resultar em um arquivo vazio.

eu faria o seguinte:

jsonstr='{"chave": "val'

if jq -e <<<"$jsonstr" &>/dev/null; then
jq <<<"$jsonstr" > meu_arquivo_de_configuração
else
echo 'erro com json' 1>&2
#exit 1
fi

testaria a saida do jq diretamente ao invés de usar a variável $?
vc só precisa testar $? se quiser verificar qual o tipo de erro ocorrido,
mas nesse caso qq erro é o suficiente para nos
como é para testes, mandamos o stderr e o stdout para /dev/null com &>/dev/null
somente se passar este teste, em seguida exececuta o jq novamente com a redireção do stdout para o arquivo
se for para desdobrar o json inteiro, não é necessário o ponto '.' no comando do jq.

já que estamos usando redirecionamento, apresento o 'here string'
então se vc tiver uma variável com o json ou o próprio texto do json, pode usar uma 'here string' ao invés de usar o cat
here string
<<< '{ "key":"value" }'
ele é os três <<<
vc lê assim, jq recebe de ...
ao invés de cat manda para jq..

e depois o redirecionamento que vc conhece, o > para sobrescrever o arquivo.
ficaria jq recebe de 'jsonstr' e manda para arquivo_de_configuração

ou para capturar a mensagem de erro do jq, que é melhor que uma mensagem de erro padrão:

jsonstr='{"chave": "val'

if jq -e <<<"$jsonstr" >/dev/null; then
jq <<<"$jsonstr" > meu_arquivo_de_configuração
fi


aqui estamos redirecionando somente o stdout ( não precisa especificar o 1) no caso do teste. se houver erro, o jq vai mandar a mensagem por stderr e não vai passar no teste. confiamos que o jq gera mensagens de erro boas para o usuário fazer a verificação.

abraço


Obrigado RogerDez,
Como o seu deu certo com a mesma linha de comando, o problema só pode ser a versão. :)
O meu jq estava na versão jq-1.5-1-a5b5cbe que insistia em não da o código de erro (mesmo com -e), atualizei para a versão jq-1.6 e problema resolvido.
Abraços,