Uzak Sunucudan Doğrudan Arşiv İndirme ve Açma: curl ve tar Kombinasyonu

Üretim ortamında çalışırken en çok sinir bozucu şeylerden biri şudur: bir sunucuya bağlanırsınız, bir şeyler indirmeniz gerekir, tarayıcınız yoktur, GUI yoktur, sadece terminal vardır. Bu durumda pek çok sysadmin şöyle bir yol izler: dosyayı önce local makineye indirir, sonra scp ile sunucuya atar, sonra açar. Oysa bu adımların tamamını tek satıra sıkıştırmak mümkün. curl ve tar kombinasyonu, uzak bir sunucudan arşiv indirip doğrudan açmak için inanılmaz derecede güçlü bir araçtır ve bunu düzgün kullanmayı öğrendikten sonra bir daha eski yönteme dönmek istemezsiniz.

Temel Kavramı Anlamak

curl bir URL’den veri çeker ve bunu stdout’a yazar. tar ise stdin’den veri okuyabilir ve açabilir. Bu iki özellik bir araya geldiğinde aradaki geçici dosyaya hiç gerek kalmaz. Pipe mekanizması devreye girer ve veri doğrudan bellekten akar.

curl -L https://example.com/dosya.tar.gz | tar -xz

Bu kadar. Ama bu kadar basit görünen komutun altında ciddi bir altyapı var ve her parametrenin neden orada olduğunu bilmek, gerçek hayatta karşılaşacağınız sorunları çözmenizi sağlar.

curl Tarafını Anlamak

curl komutu bu kullanım senaryosunda birkaç kritik parametreyle çalışır.

-L (–location): Yönlendirmeleri takip et. GitHub, S3, CDN gibi servislerin neredeyse tamamı HTTP redirect kullanır. Bu parametreyi unutursanız arşiv yerine 301/302 yanıtının HTML içeriğini tar‘a göndermiş olursunuz ve tar da tahmin edilebileceği üzere bunu açmaya çalışarak anlamsız hata mesajları üretir.

-s (–silent): İlerleme çubuğunu ve hata mesajlarını bastırır. Script içinde kullanırken genellikle istersiniz ama interaktif terminalde bazen görmek istersiniz.

-f (–fail): HTTP hata kodlarında (4xx, 5xx) curl’ün başarısız çıkış kodu döndürmesini sağlar. Script’lerde kritik öneme sahiptir; bu olmadan sunucu 404 dönse bile curl başarılı çıkar ve tar o hata HTML’ini açmaya çalışır.

-o /dev/null: Çıktıyı yok saymak istediğinizde kullanırsınız, ama bu kombinasyonda kullanmayız tabii.

–progress-bar: -s kadar sessiz değil ama ilerleme çubuğunu minimal gösterir, büyük dosyalarda kullanışlıdır.

tar Tarafını Anlamak

tar komutunun bu senaryodaki parametreleri de bir o kadar önemli.

-x: Extract, yani arşivi aç.

-z: gzip sıkıştırmasını kullan (.tar.gz veya .tgz dosyaları için).

-j: bzip2 sıkıştırmasını kullan (.tar.bz2 dosyaları için).

-J: xz sıkıştırmasını kullan (.tar.xz dosyaları için). Modern Linux dağıtımlarının kaynak paketleri çoğunlukla xz kullanır.

-v: Verbose, açılan dosyaları listeler. İnteraktif kullanımda güzel ama script’te genellikle gürültü yaratır.

-C /hedef/dizin: Arşivi belirtilen dizine aç. Bu parametreyi çok sık unutuyorum ve her seferinde yanlış yere açılmış dosyaları temizlemek zorunda kalıyorum.

-f –: Dosya adı olarak tire işareti stdin’den oku anlamına gelir. Bazı eski tar sürümlerinde bunu açıkça belirtmeniz gerekir; modern versiyonlarda pipe kullandığınızda otomatik algılar ama alışkanlık olarak yazmakta fayda var.

Gerçek Dünya Senaryoları

Node.js Binary İndirme ve Kurma

Bir üretim sunucusunda package manager olmadan Node.js kurmak istiyorsunuz. Klasik senaryo:

curl -L https://nodejs.org/dist/v20.11.0/node-v20.11.0-linux-x64.tar.xz | 
  tar -xJ -C /usr/local --strip-components=1

Burada –strip-components=1 parametresi kritik. node-v20.11.0-linux-x64/ gibi bir üst dizin olmadan direkt /usr/local/bin/, /usr/local/lib/ şeklinde açar. Bu olmadan /usr/local/node-v20.11.0-linux-x64/bin/node gibi bir yola düşersiniz ve PATH ayarlamak zorunda kalırsınız.

Go Toolchain Kurulumu

DevOps mühendislerinin sık yaptığı bir işlem:

curl -fsSL https://go.dev/dl/go1.22.0.linux-amd64.tar.gz | 
  tar -xz -C /usr/local

Burada -fsSL kombinasyonuna dikkat edin. -f hata durumunda başarısız çık, -s sessiz çalış, -S sessiz modda bile hataları göster, -L yönlendirmeleri takip et. Bu dörtlü, script’lerde neredeyse standart hale gelmiştir.

Belirli Bir Dizine Açma

Bazen sisteme yaymak değil, izole bir yere kurmak istersiniz:

mkdir -p /opt/myapp
curl -fsSL https://releases.example.com/myapp-v2.1.tar.gz | 
  tar -xz -C /opt/myapp --strip-components=1

GitHub Release İndirme

GitHub API üzerinden release asset indirmek biraz farklı çalışır:

REPO="prometheus/prometheus"
VERSION="2.49.1"
OS="linux"
ARCH="amd64"

curl -fsSL "https://github.com/${REPO}/releases/download/v${VERSION}/prometheus-${VERSION}.${OS}-${ARCH}.tar.gz" | 
  tar -xz -C /tmp

GitHub için -L şart çünkü release indirme linkleri her zaman redirect içerir. Bunu bir kez atlamıştım ve neden boş dosya aldığımı anlamak için 10 dakika harcamıştım.

Checksum Doğrulaması: İhmal Edilmemesi Gereken Adım

Güvenlik açısından bakıldığında, pipe üzerinden gelen veriyi doğrudan açmak ciddi bir risk taşır. Araya giren biri (MITM) veya değiştirilmiş bir kaynak, zararlı içerik gönderebilir. Bu yüzden checksum doğrulaması şart.

Sorun şu ki pipe kullandığınızda dosyayı diske yazmadan checksum alamazsınız. Birkaç çözüm yolu var:

Yöntem 1: Önce indir, doğrula, sonra aç

curl -fsSL https://example.com/package.tar.gz -o /tmp/package.tar.gz
echo "beklenen_sha256_hash  /tmp/package.tar.gz" | sha256sum -c
tar -xz -C /opt -f /tmp/package.tar.gz
rm /tmp/package.tar.gz

Bu yöntem daha güvenli ama geçici dosya bırakır.

Yöntem 2: tee ile hem doğrula hem pipe et

curl -fsSL https://example.com/package.tar.gz | 
  tee >(sha256sum > /tmp/checksum.txt) | 
  tar -xz -C /opt

# Doğrulama
echo "beklenen_hash  -" | diff - /tmp/checksum.txt

Yöntem 3: GPG imzalı release’lerde

curl -fsSL https://example.com/package.tar.gz.asc -o /tmp/package.asc
curl -fsSL https://example.com/package.tar.gz | 
  tee /tmp/package.tar.gz | 
  tar -xz -C /opt

gpg --verify /tmp/package.tar.gz.asc /tmp/package.tar.gz

Üretim ortamında kesinlikle checksum doğrulamasını atlamamalısınız. Geliştirme veya test ortamında tolerans gösterilebilir ama üretimde bu adım pazarlık konusu değil.

Hata Yönetimi ve Script Güvenliği

Tek satırlık komutlar interaktif kullanım için mükemmeldir ama script içine aldığınızda hata yönetimi kritik önem kazanır.

#!/bin/bash
set -euo pipefail

INSTALL_DIR="/opt/myapp"
DOWNLOAD_URL="https://releases.example.com/myapp-v2.1.tar.gz"
EXPECTED_SHA256="abc123def456..."

# Geçici dosyaya indir
TMPFILE=$(mktemp)
trap "rm -f ${TMPFILE}" EXIT

echo "İndiriliyor: ${DOWNLOAD_URL}"
if ! curl -fsSL --retry 3 --retry-delay 2 "${DOWNLOAD_URL}" -o "${TMPFILE}"; then
  echo "HATA: İndirme başarısız oldu" >&2
  exit 1
fi

# Checksum doğrula
echo "${EXPECTED_SHA256}  ${TMPFILE}" | sha256sum -c || {
  echo "HATA: Checksum uyuşmuyor, dosya bozuk veya değiştirilmiş olabilir" >&2
  exit 1
}

# Dizini hazırla
mkdir -p "${INSTALL_DIR}"

# Aç
tar -xzf "${TMPFILE}" -C "${INSTALL_DIR}" --strip-components=1
echo "Kurulum tamamlandı: ${INSTALL_DIR}"

Bu script’teki kritik noktalar:

  • set -euo pipefail: Herhangi bir hata script’i durdurur, tanımsız değişken kullanımı hata verir, pipe’da herhangi bir komut başarısız olursa tüm pipe başarısız sayılır.
  • trap: Script herhangi bir şekilde bittiğinde geçici dosyayı temizler.
  • –retry 3: Geçici ağ sorunlarında tekrar dener. Üretim script’lerinde bunu mutlaka ekleyin.

Bandwidth ve Performans Optimizasyonu

Büyük dosyalar indirirken birkaç optimizasyon yapılabilir.

Hız limitleme: Üretim ortamında ağ trafiğini patlatmamak için:

curl -fsSL --limit-rate 10M https://example.com/bigfile.tar.gz | 
  tar -xz -C /opt

Paralel indirme ve açma: tar açarken CPU kullanır, curl ise network I/O bekler. Pipe bu ikisini doğal olarak paralelize eder. Büyük arşivlerde bu ciddi zaman kazancı sağlar. Benchmark yaptığımda 2GB’lık bir arşivi önce indirip sonra açmak yerine pipe ile yapmak yaklaşık %30 daha hızlı oldu.

İlerleme takibi: Uzun süren indirmelerde ne olduğunu görmek için:

curl -fSL https://example.com/largefile.tar.gz | 
  pv -pterb | 
  tar -xz -C /opt

pv (pipe viewer) kuruluysa hem hız hem de tamamlanma tahmini gösterir. Uzun süren kurulum script’lerinde bunu eklemek kullanıcı deneyimini önemli ölçüde iyileştirir.

Farklı Arşiv Formatlarına Göre Yaklaşım

Farklı projeler farklı sıkıştırma formatları kullanır ve tar‘a doğru parametreyi vermek gerekir.

.tar.gz veya .tgz dosyaları için:

curl -fsSL https://example.com/package.tar.gz | tar -xz -C /opt

.tar.bz2 dosyaları için:

curl -fsSL https://example.com/package.tar.bz2 | tar -xj -C /opt

.tar.xz dosyaları için:

curl -fsSL https://example.com/package.tar.xz | tar -xJ -C /opt

.tar.zst dosyaları için (modern sistemlerde giderek yaygınlaşıyor, Arch Linux paketleri bu formatı kullanıyor):

curl -fsSL https://example.com/package.tar.zst | tar -x --zstd -C /opt

Peki format bilinmiyorsa ne yapmalı? Modern tar sürümleri otomatik algılama yapar ama pipe kullanırken bu çalışmaz çünkü tar başlığı okumadan önce decompress metodunu belirleyemez. Bu durumda en sağlıklı yol önce indirip sonra açmaktır:

curl -fsSL https://example.com/unknown-format -o /tmp/archive
file /tmp/archive  # Format nedir görelim
tar -xaf /tmp/archive -C /opt  # -a otomatik format tespiti

Proxy Arkasında Çalışmak

Kurumsal ortamlarda sık karşılaşılan durum: proxy arkasında internet erişimi. curl bu konuda oldukça esnek.

# Ortam değişkeni ile
export https_proxy="http://proxy.sirket.local:8080"
export http_proxy="http://proxy.sirket.local:8080"
export no_proxy="10.0.0.0/8,192.168.0.0/16,localhost"

curl -fsSL https://example.com/package.tar.gz | tar -xz -C /opt

# Veya doğrudan parametre ile
curl -fsSL -x http://proxy.sirket.local:8080 
  https://example.com/package.tar.gz | tar -xz -C /opt

Kimlik doğrulama gerektiren proxy’ler için:

curl -fsSL -x http://proxy.sirket.local:8080 
  --proxy-user kullanici:sifre 
  https://example.com/package.tar.gz | tar -xz -C /opt

Şifreyi komut satırına yazmak güvenlik açığı yaratır. Bunun yerine ~/.netrc dosyasını veya CURLOPT_PROXYUSERPWD ortam değişkenini kullanın.

Self-Signed Sertifika Sorunu

İntranet ortamlarında veya test ortamlarında self-signed sertifikalar can sıkıcı olabilir.

# Sertifika doğrulamasını devre dışı bırak (SADECE güvenilir iç ağlarda)
curl -fsSLk https://internal.sirket.local/package.tar.gz | tar -xz -C /opt

-k veya –insecure parametresi sertifika doğrulamasını atlar. İnternet’e açık bir kaynaktan indirirken bunu asla kullanmayın. İç ağda bile mümkünse şirketin CA sertifikasını sisteme eklemek daha doğrudur:

# CA sertifikasını sisteme ekle (Ubuntu/Debian)
cp sirket-ca.crt /usr/local/share/ca-certificates/
update-ca-certificates

# Veya curl'e özel olarak belirt
curl -fsSL --cacert /path/to/sirket-ca.crt 
  https://internal.sirket.local/package.tar.gz | tar -xz -C /opt

Docker ve Container Ortamlarında Kullanım

Dockerfile’larda bu kombinasyon çok sık kullanılır ve burada bazı best practice’ler devreye girer.

FROM ubuntu:22.04

ARG NODE_VERSION=20.11.0

RUN apt-get update && apt-get install -y curl && 
    curl -fsSL "https://nodejs.org/dist/v${NODE_VERSION}/node-v${NODE_VERSION}-linux-x64.tar.xz" | 
    tar -xJ -C /usr/local --strip-components=1 && 
    apt-get purge -y curl && 
    apt-get autoremove -y && 
    rm -rf /var/lib/apt/lists/*

Bu Dockerfile’da dikkat edilecek noktalar: curl kurulumu ve kullanımı aynı RUN layer’ında yapılıyor. Böylece layer cache’de curl kalıntısı bırakılmıyor ve image boyutu küçülüyor. Gerçek projelerde ben her zaman bu yaklaşımı tercih ederim.

Ansible ve Otomasyon Entegrasyonu

Ansible playbook’larında bu kombinasyonu doğrudan shell modülüyle kullanabilirsiniz ama daha temiz bir yol var:

- name: Node.js kur
  ansible.builtin.shell: |
    curl -fsSL "{{ node_download_url }}" | 
    tar -xJ -C /usr/local --strip-components=1
  args:
    creates: /usr/local/bin/node
  environment:
    https_proxy: "{{ proxy_url | default('') }}"

creates parametresi idempotency sağlar; dosya zaten varsa komutu tekrar çalıştırmaz. Bu Ansible’da temel bir prensip ve otomasyon script’lerinde her zaman göz önünde bulundurulmalı.

Sık Yapılan Hatalar ve Çözümleri

Hata: “This does not look like a tar archive”

Genellikle curl’ün HTML içeriği veya hata mesajı döndürdüğünü gösterir. -f parametresini ekleyin ve URL’yi browser’da kontrol edin.

Hata: “stdin: not a tty”

Bazı sistemlerde tar‘ın stdin’den okuyacağını anlamadığı durumlarda oluşur. tar -xzf - şeklinde açık olarak belirtin.

Hata: Yanlış dizine açılma

-C parametresini unutmak çok yaygın. Şu an hangi dizinde olduğunuzu her zaman kontrol edin: pwd && curl ... | tar -xz -C /istenen/dizin

Hata: Permission denied

Hedef dizine yazma izniniz yok. sudo ile çalıştırın:

curl -fsSL https://example.com/package.tar.gz | sudo tar -xz -C /usr/local

sudo curl ... | tar yerine curl ... | sudo tar kullanmak daha güvenlidir. Sadece tar‘ın root yetkisiyle çalışmasını sağlarsınız, curl değil.

Sonuç

curl ve tar kombinasyonu basit görünse de detaylarına hakim olmak, üretim ortamında çok daha güvenilir ve tekrarlanabilir kurulum prosedürleri oluşturmanızı sağlar. -fsSL dörtlüsünü ezberleyin, checksum doğrulamasını hiç atlamamaya çalışın, script’lerde set -euo pipefail ile başlayın. --strip-components parametresi ise benim en çok zaman kaybettiren detay oldu, öğrenince vazgeçemiyorsunuz.

Bu kombinasyonun güzelliği şu: geçici dosya bırakmıyor, bant genişliğini verimli kullanıyor, tek satırla hem indir hem aç işini hallediyor. CI/CD pipeline’larında, Dockerfile’larda, Ansible playbook’larında ve interaktif terminal kullanımında bu kalıp sürekli karşınıza çıkacak. Ne yaptığını anladığınızda da her seferinde ona biraz daha güveniyorsunuz.

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir