JQ untuk Shell Script Linux: Cara Parse JSON API dengan Aman di Automation Production
Last updated on
Target keyword: jq shell script linux parse json api automation
Search intent: Problem-solving / Best-practice
Monthly keyword cluster: linux shell scripting, bash scripting linux, automasi tugas linux
Weekly intent rotation: Troubleshooting + implementasi praktis
Kalau kamu sering bikin automasi berbasis shell script, cepat atau lambat kamu bakal ketemu data JSON dari API: status deployment, hasil health check, daftar job, sampai token metadata. Tantangannya bukan cuma “gimana ngambil nilainya”, tapi gimana ngambilnya dengan aman saat data tidak konsisten, API timeout, atau respons error tapi HTTP status-nya tetap 200.
Di sinilah jq jadi senjata wajib. Dengan jq, kamu bisa parse JSON secara konsisten, validasi struktur data, kasih fallback value, dan bikin alur script lebih tahan banting di production.
Artikel ini fokus ke use case nyata: integrasi API di shell script Linux yang dipakai untuk cron/systemd timer atau pipeline harian. Targetnya sederhana: script kamu tetap kebaca, gampang di-debug, dan minim false success.
Kenapa parsing JSON di shell script sering bikin masalah?
Masalah paling umum biasanya ini:
- Parsing pakai
grep/cut/seduntuk JSON (rapuh banget kalau format berubah sedikit). - Script tidak bedain network error, HTTP error, dan business logic error.
- Nilai kosong/null tidak ditangani, akhirnya command lanjut dengan data invalid.
- Logging kurang jelas, jadi pas error tim bingung masalahnya di mana.
Kalau script itu menyentuh workflow penting (backup, deployment, sinkron data), satu parsing error kecil bisa jadi incident besar.
Prasyarat
- Linux server / VM dengan Bash.
curluntuk request API.jquntuk parse JSON.
Instal cepat:
# Ubuntu/Debian
sudo apt-get update && sudo apt-get install -y jq curl
# Verifikasi
jq --version
curl --version | head -n1
Pola dasar: curl + jq yang aman
Banyak script gagal karena langsung:
curl -s https://api.example.com/jobs | jq -r '.data[0].id'
Ini “jalan” saat semua normal, tapi rapuh. Versi yang lebih aman:
#!/usr/bin/env bash
set -Eeuo pipefail
API_URL="https://api.example.com/jobs"
TMP_JSON="$(mktemp)"
trap 'rm -f "$TMP_JSON"' EXIT
HTTP_CODE=$(curl -sS --connect-timeout 5 --max-time 20 \
-H "Accept: application/json" \
-o "$TMP_JSON" \
-w "%{http_code}" \
"$API_URL")
if [[ "$HTTP_CODE" -lt 200 || "$HTTP_CODE" -ge 300 ]]; then
echo "[ERROR] HTTP $HTTP_CODE from $API_URL"
echo "[DEBUG] body: $(head -c 300 "$TMP_JSON")"
exit 1
fi
if ! jq empty "$TMP_JSON" >/dev/null 2>&1; then
echo "[ERROR] Response bukan JSON valid"
exit 1
fi
JOB_ID=$(jq -r '.data[0].id // empty' "$TMP_JSON")
if [[ -z "$JOB_ID" ]]; then
echo "[ERROR] data[0].id kosong / tidak ada"
exit 1
fi
echo "[INFO] JOB_ID=$JOB_ID"
Poin penting dari pola ini:
- Pisahkan HTTP code dan body biar validasi jelas.
- Cek JSON valid dulu dengan
jq empty. - Pakai fallback
// emptysupaya null tidak diam-diam dianggap sukses. - Gunakan
set -Eeuo pipefailagar error tidak ketelan.
Teknik jq yang paling kepakai di automation
1) Ambil nilai dengan fallback aman
jq -r '.metadata.region // "unknown"' response.json
Kalau field tidak ada/null, tetap dapat nilai default.
2) Validasi field wajib sebelum lanjut
jq -e '.status == "ok" and (.data | type == "array")' response.json >/dev/null
-e bikin exit code non-zero kalau ekspresi false. Cocok untuk guard clause di script.
3) Filter item berdasarkan kondisi
jq -r '.jobs[] | select(.state=="failed") | .id' response.json
Ini enak buat incident triage otomatis.
4) Bentuk output ringkas untuk logging
jq -r '{request_id, status, count: (.data|length)}' response.json
Log jadi lebih padat dan relevan.
5) Hindari error saat array kosong
jq -r '.data[0]?.id // empty' response.json
Operator ? mencegah crash saat elemen tidak ada.
Contoh use case nyata: health check API + retry sederhana
Misal kamu mau script health check untuk endpoint internal. Tujuan kita:
- Retry kalau timeout/intermiten.
- Gagal kalau status app bukan
healthy. - Log ringkas untuk observability.
#!/usr/bin/env bash
set -Eeuo pipefail
URL="https://internal-api.example.com/health"
MAX_RETRY=3
SLEEP_SEC=2
log() {
echo "[$(date '+%F %T')] $*"
}
attempt=1
while (( attempt <= MAX_RETRY )); do
BODY_FILE="$(mktemp)"
trap 'rm -f "$BODY_FILE"' RETURN
HTTP_CODE=$(curl -sS --connect-timeout 3 --max-time 10 \
-o "$BODY_FILE" -w "%{http_code}" "$URL" || echo "000")
if [[ "$HTTP_CODE" == "000" ]]; then
log "WARN network error (attempt $attempt/$MAX_RETRY)"
elif [[ "$HTTP_CODE" -ge 200 && "$HTTP_CODE" -lt 300 ]]; then
if jq -e '.status == "healthy"' "$BODY_FILE" >/dev/null 2>&1; then
VERSION=$(jq -r '.version // "unknown"' "$BODY_FILE")
LATENCY=$(jq -r '.latency_ms // -1' "$BODY_FILE")
log "OK status=healthy version=$VERSION latency_ms=$LATENCY"
exit 0
else
log "WARN app unhealthy (attempt $attempt/$MAX_RETRY)"
log "DEBUG $(jq -c '{status, message, code}' "$BODY_FILE" 2>/dev/null || head -c 200 "$BODY_FILE")"
fi
else
log "WARN http=$HTTP_CODE (attempt $attempt/$MAX_RETRY)"
fi
(( attempt++ ))
sleep "$SLEEP_SEC"
done
log "ERROR health check failed after $MAX_RETRY attempts"
exit 1
Script ini udah cukup aman untuk dipasang di cron/systemd timer karena:
- Tidak menganggap respons 200 sebagai pasti sukses.
- Ada retry terkontrol.
- Ada log yang bisa langsung dipakai investigasi.
Troubleshooting umum saat pakai jq
Masalah 1: jq: command not found
Penyebab: package jq belum terpasang di host runtime (sering kejadian di container slim).
Solusi:
- Tambahkan
jqdi image build/deploy. - Buat preflight check di awal script.
command -v jq >/dev/null || { echo "jq belum terpasang"; exit 1; }
Masalah 2: Output kosong padahal field ada
Penyebab: path JSON salah atau struktur respons berubah.
Solusi: inspect struktur dulu.
jq '.' response.json | less
jq -r 'paths | join(".")' response.json | head -n 80
Masalah 3: Script tetap lanjut walau ekspresi jq false
Penyebab: tidak pakai -e atau tidak cek exit code.
Solusi:
if ! jq -e '.status=="ok"' response.json >/dev/null; then
echo "status bukan ok"
exit 1
fi
Masalah 4: JSON invalid dari upstream
Penyebab: API gateway/error page HTML dikirim sebagai body.
Solusi: selalu validasi JSON sebelum parse field.
jq empty response.json >/dev/null 2>&1 || exit 1
Checklist implementasi production
- Selalu pisahkan HTTP status dan body respons.
- Gunakan
jq emptyuntuk cek validitas JSON. - Pakai
jq -euntuk validasi kondisi wajib. - Terapkan fallback (
// empty/ default value) untuk field opsional. - Tambahkan retry + timeout yang realistis.
- Pastikan log memuat context minimum: endpoint, status, attempt, request id (jika ada).
- Uji skenario error: timeout, 500, payload null, payload schema berubah.
Internal link rekomendasi
Biar implementasi makin matang, kamu bisa lanjut ke artikel terkait ini:
- Shell Script Retry, Backoff, Timeout Patterns di Linux Automation
- Shell Script Observability: Logging, Metrics, Alerting Linux Production
- Shell Script Preflight Checks untuk Reliability Automation
- Linux Shell Scripting: Troubleshooting dan Solusi Nyata untuk Production
FAQ (Schema-ready)
Format tanya-jawab di bawah sudah siap dipetakan ke
FAQPageJSON-LD.
1) Kapan sebaiknya pakai jq dibanding grep/sed untuk JSON?
Begitu input kamu berupa JSON dari API, langsung pakai jq. grep/sed mungkin terlihat cepat di awal, tapi rentan rusak saat struktur JSON berubah dan sulit dijaga untuk production.
2) Apakah jq cukup aman untuk script production?
Aman, selama dipakai dengan pola yang benar: validasi JSON (jq empty), validasi kondisi (jq -e), fallback value, plus timeout/retry di layer request (curl).
3) Gimana cara bikin script gagal cepat saat data penting hilang?
Gunakan guard clause setelah parsing:
ID=$(jq -r '.data.id // empty' resp.json)
[[ -n "$ID" ]] || { echo "ID wajib tidak ada"; exit 1; }
4) Kalau API kadang lambat, apa cukup retry saja?
Jangan retry buta. Kombinasikan connect-timeout, max-time, retry terbatas, dan logging attempt. Kalau tetap gagal, exit non-zero supaya monitoring bisa nangkap.
Penutup
jq bukan cuma tools “biar parsing lebih rapi”, tapi pondasi penting buat automation shell script yang tahan gangguan. Dengan pola validasi JSON, guard clause, retry terkontrol, dan logging yang jelas, kamu bisa turunin risiko false success secara signifikan.
Kalau kamu lagi audit script lama, mulai dari endpoint paling kritis dulu: ganti parsing rapuh ke jq, tambah validation gate, lalu uji skenario gagal. Perubahan kecil ini biasanya langsung kerasa dampaknya di stabilitas production.
Komentar
Memuat komentar...
Tulis Komentar