Menerapkan Zsh untuk workflow networking dan remote: helper SSH dan SCP, alias rsync untuk sinkronisasi aman, wrapper curl dan wget yang ergonomis, serta memanfaatkan completion bawaan Zsh untuk Docker, kubectl, dan git dalam pekerjaan harian di banyak host

Setelah di episode 17 kalian menulis skrip yang aman, pada episode ini kita menerapkan Zsh di lapangan: workflow networking dan remote. Sebagian besar pekerjaan DevOps dan SysAdmin melibatkan banyak host — SSH ke server, menyalin file, mengirim request HTTP, mengelola container dan cluster. Zsh punya dua kekuatan di sini: completion bawaan untuk semua CLI besar (ssh, scp, rsync, docker, kubectl), dan alias/function yang mengubah perintah panjang menjadi satu ketikan.
Episode ini menggabungkan keduanya menjadi toolkit remote yang praktis — lengkap dengan prinsip keamanan episode 17.
Setelah compinit (episode 6), Zsh menyediakan completion untuk SSH yang memahami ~/.ssh/config:
# ~/.ssh/config punya host:
# Host prod-web
# Host staging-api
ssh prod<Tab> # melengkapi menjadi "prod-web"Begitu juga scp — melengkapi kedua sisi path remote:
scp user@prod-web:/var/log/app<Tab>
# melengkapi path di sisi remote berdasarkan sesiIni menghemat banyak ketikan: Zsh membuka sesi untuk melengkapi path remote, menawarkan direktori yang benar.
Alias dan function untuk mempercepat koneksi remote:
alias ssh-prod='ssh prod-web'
alias ssh-staging='ssh staging-api'
# tanpa host config — pakai user default:
alias prod='ssh deploy@10.0.0.5'Function untuk kasus yang lebih kompleks — SSH dengan log ke file:
#!/usr/bin/env zsh
# Jalankan perintah remote dan catat ke file
ssh_run() {
local host="$1"; shift
local logfile="/tmp/ssh_${host}.log"
print "==> $host: $*" >> "$logfile"
ssh "$host" "$@" 2>&1 | tee -a "$logfile"
}Pattern local host="$1"; shift sangat umum: ambil argumen pertama sebagai host, sisanya sebagai perintah remote.
rsync adalah tool utama sinkronisasi (pelajari lengkap di series learn-rsync). Zsh menambah completion untuk remote path seperti scp. Alias yang umum:
alias sync-up='rsync -avz --delete'
alias sync-down='rsync -avz'sync-up ./public/ prod-web:/var/www/site/
sync-down prod-web:/var/www/site/app.log ./backup/-a archive (pertahankan permission, timestamps), -v verbose, -z kompresi, --delete hapus file tujuan yang tidak ada di sumber.Untuk sinkronisasi satu arah yang sering diulang, bungkus jadi function dengan guard:
deploy_site() {
local target="${1:?host tujuan wajib diisi}"
rsync -avz --delete --exclude 'node_modules' \
./dist/ "${target}:/var/www/site/" || return 1
print "Deploy selesai ke $target"
}curl tanpa alias masih membosankan — wrapper mengubahnya jadi ergonomis:
alias curl-get='curl -sS -w "\n%{http_code}\n"'
alias curl-json='curl -sS -H "Content-Type: application/json"'
alias curl-head='curl -sSI'
api() {
local method="$1" url="$2"; shift 2
curl -sS -X "$method" "$url" "$@"
}
# api GET https://api.example.com/health
# api POST https://api.example.com/items -d '{"name":"x"}'Tip
Tambahkan -w "\n%{http_code}\n" ke curl di skrip agar status HTTP selalu tercetak — ini menyelamatkan saat debugging API di terminal yang sama dengan server. Kombinasi dengan jq untuk pretty-print JSON membuat API debugging jauh lebih nyaman.
Wrapper wget senada:
alias wget='wget --show-progress'
alias wget-mirror='wget -mk'Zsh sudah menyertakan completion untuk docker dan kubectl — bahkan menampilkan nama image/container yang ada:
docker run ubun<Tab> # menawarkan image ubuntu
docker stop <Tab> # daftar container yang berjalan
kubectl get pod<Tab> # menampilkan subresource: pods, poddisruptionbudgets
kubectl describe <Tab> # daftar nama pod di namespace aktifkubectl juga melengkapi nama resource dan nama pod nyata — ini yang membuat compinit sepadan.
alias d='docker'
alias dc='docker compose'
alias dps='docker ps'
alias dlogs='docker logs -f'
# context awareness
dk() {
local ctx="$1"; shift
docker --context="$ctx" "$@"
}alias k='kubectl'
alias kg='kubectl get'
alias kgp='kubectl get pods'
alias kd='kubectl describe'
alias kl='kubectl logs -f'
alias kx='kubectl exec -it'
# switch namespace dengan cepat
kns() {
kubectl config set-context --current --namespace="$1"
}
kctx() {
kubectl config use-context "$1"
}Wrapper satu huruf (k, d) + completion bawaan adalah kombinasi yang dipakai ribuan DevOps engineer setiap hari.
Zsh completion git sangat detail — melengkapi branch, tag, dan argumen:
git checkout fea<Tab> # melengkapi branch feature/*
git push origin <Tab> # daftar remote branch
git remote -vAlias untuk workflow remote umum:
alias gpush='git push origin HEAD'
alias gpull='git pull --rebase'
alias gf='git fetch --all --prune'
alias grm='git remote -v'Gabungkan semua dalam satu alur nyata — deploy statis ke server via rsync, verifikasi via ssh:
./build.sh && \
sync-up ./dist/ prod-web:/var/www/site/ && \
ssh prod-web 'systemctl reload nginx && curl -sI localhost | head -1'Satu baris, tiga fase, semuanya punya guard (build gagal → tidak deploy; rsync gagal → tidak reload). Inilah kekuatan skrip + alias + completion yang dibangun sepanjang series ini.
--delete tanpa dry-run — selalu -n (dry-run) dulu di direktori produksi; ls test tidak cukup.-f — di skrip, tambahkan -f agar curl gagal (exit non-zero) pada HTTP error, bukan hanya koneksi error.kctx dan konfigurasi --namespace eksplisit; kesalahan context = operasi di cluster yang salah.Inti yang harus dibawa pulang:
~/.ssh/config, remote path scp/rsync, dan semua subcommand docker/kubectl/git.-avz --delete) menyederhanakan sinkronisasi.-w "%{http_code}" dan -f membuat API debugging jelas.k, d, g) + completion = produktivitas DevOps harian.Di episode 19 selanjutnya kita akan membahas testing skrip dengan zunit dan shellcheck — menulis unit test Zsh dengan zunit, assertion helpers, menjalankan shellcheck sebagai lint di CI, dan menyusun CI job untuk skrip shell agar perubahan tidak merusak behavior. Sampai jumpa di episode 19!