Sunucu yönetiminde zamanlanmış görevler denilince akla hemen cron geliyor. Ancak cron, tekrar eden işler için tasarlanmış bir araç. Peki ya sadece bir kez, belirli bir saatte çalışmasını istediğiniz bir komut veya script varsa? İşte tam bu noktada at komutu devreye giriyor. “Şu anda değil, akşam 11’de çalıştır” demek istediğinizde at sizin en iyi dostunuz oluyor.
at Komutu Nedir ve Neden Kullanılır?
at, Unix/Linux sistemlerinde belirli bir zamanda tek seferlik görev çalıştırmanızı sağlayan bir komut satırı aracıdır. Cron’dan temel farkı şu: cron periyodik görevler için (her gün, her pazartesi, her saat başı gibi), at ise yalnızca bir kez çalışacak görevler için kullanılır.
Gerçek dünya senaryolarını düşünelim. Cuma akşamı eve gidiyorsunuz ama gece yarısı bir veritabanı yedekleme işlemi başlatmanız gerekiyor. Ya da bir yazılım güncellemesi saat 03:00’te yapılacak ve siz orada olmak istemiyorsunuz. Belki de bir müşteri sunucusunda çalışma saatleri dışında bir servis yeniden başlatma işi var. Bunların hepsi at komutu için biçilmiş kaftan.
at Kurulumu ve Servis Kontrolü
Çoğu Linux dağıtımında at paketi kurulu gelir, ancak minimal kurulumlar veya container imajları söz konusu olduğunda kontrol etmek gerekir.
# Ubuntu/Debian sistemlerde kurulum
sudo apt-get install at
# RHEL/CentOS/Rocky Linux sistemlerde
sudo dnf install at
# Servis durumunu kontrol et
sudo systemctl status atd
# Servisi başlat ve otomatik başlayacak şekilde ayarla
sudo systemctl enable --now atd
atd daemon’ının çalışıyor olması kritik. Servis çalışmıyorsa planladığınız hiçbir görev hayata geçmeyecektir. Bu yüzden kurulumdan sonra servis kontrolünü ihmal etmeyin.
Temel Kullanım Sözdizimi
at komutunun genel sözdizimi oldukça sade:
at [seçenekler] ZAMAN
Komutu girdikten sonra bir at> istemi açılır. Buraya çalıştırmak istediğiniz komutları yazarsınız. İşiniz bitince Ctrl+D ile girişi tamamlarsınız. Alternatif olarak bir dosyadan da komut verebilirsiniz.
# Saat 22:30'da çalışacak görev oluşturma
at 22:30
at> /usr/local/bin/backup.sh
at> <EOT> # Ctrl+D ile çıkış
Komut girildikten sonra sistem size görevin numarasını ve çalışma zamanını onaylar:
job 3 at Mon Jan 15 22:30:00 2024
Zaman Formatları: Esnek ve Güçlü
at komutunun güçlü yanlarından biri zaman formatlarındaki esneklik. İnsan diline yakın ifadeler kullanabiliyorsunuz.
# Mutlak zaman formatları
at 14:30 # Bugün saat 14:30
at 2:30pm # Bugün öğleden sonra 2:30
at 14:30 tomorrow # Yarın saat 14:30
at 14:30 Jul 25 # 25 Temmuz saat 14:30
at 14:30 25.07.2024 # Aynı şey, noktalı format
# Göreli zaman formatları
at now + 30 minutes # 30 dakika sonra
at now + 2 hours # 2 saat sonra
at now + 1 day # Yarın şu saatte
at now + 3 weeks # 3 hafta sonra
# Özel zaman kelimeleri
at midnight # Gece yarısı
at noon # Öğlen 12:00
at teatime # Saat 16:00 (İngiliz geleneği!)
at tomorrow # Yarın şu saatte
at next week # Gelecek hafta
teatime gibi eğlenceli sabitler de var. Sisteme “teatime” yazarsanız saat 16:00 anlamına gelir. Bunu iş arkadaşlarınıza gösterdiğinizde mutlaka güler geçerler.
Dosyadan Komut Çalıştırma
Karmaşık görevler için doğrudan komut satırından giriş yapmak yerine bir betik dosyası kullanmak çok daha pratik:
# Script dosyasından görev yükleme
at 03:00 tomorrow < /usr/local/bin/maintenance.sh
# Veya -f parametresi ile
at -f /usr/local/bin/maintenance.sh 03:00 tomorrow
-f dosya_adı: Komutları klavyeden değil belirtilen dosyadan okur.
Bu yöntem özellikle birden fazla komut çalıştırmanız gereken durumlarda hayat kurtarıcı. Script dosyanızı hazırlıyorsunuz, test ediyorsunuz, sonra at ile zamanlıyorsunuz.
Bekleyen Görevleri Listeleme
Planladığınız görevleri görmek için atq komutunu veya at -l kullanabilirsiniz. İkisi de aynı işi yapar:
# Görev listesini görüntüle
atq
# Alternatif yöntem
at -l
Çıktı şöyle görünür:
5 Mon Jan 15 03:00:00 2024 a kullaniciadi
6 Tue Jan 16 14:30:00 2024 a kullaniciadi
7 Wed Jan 17 22:00:00 2024 b root
Buradaki sütunlar sırasıyla: görev numarası, çalışma tarihi/saati, kuyruk harfi (a, b, c…) ve görevi oluşturan kullanıcıdır.
Root olarak çalışırken tüm kullanıcıların görevlerini görebilirsiniz. Normal kullanıcılar sadece kendi görevlerini görür.
Görev İçeriğini İnceleme
Planlanmış bir görevin ne yapacağını görmek isterseniz at -c kullanırsınız:
# 5 numaralı görevin içeriğini görüntüle
at -c 5
Bu komut görevin tüm çevre değişkenleri ve çalışacak komutlarla birlikte tam içeriğini döker. Uzun bir çıktı alırsınız çünkü at, görevi oluşturduğunuz anki tüm ortam değişkenlerini de kaydeder. Bu aslında çok önemli bir özellik: görev çalıştığında aynı çevre değişkenleri aktif olacak demektir.
Görev İptal Etme
Planladığınız bir görevi iptal etmek için atrm komutunu veya at -d kullanabilirsiniz:
# 5 numaralı görevi iptal et
atrm 5
# Alternatif yöntem
at -d 5
# Birden fazla görevi iptal et
atrm 5 6 7
atrm veya at -d: Belirtilen numara(lar)daki görevi kuyruktan kaldırır.
Dikkat: Görev zaten çalışmaya başlamışsa iptal edemezsiniz. İptal işlemi yalnızca kuyrukta bekleyen görevler için geçerlidir.
at Kuyruğu Öncelikleri
at komutunun az bilinen ama kullanışlı bir özelliği kuyruk önceliklendirmesidir. A’dan Z’ye kadar 52 farklı kuyruk kullanabilirsiniz:
# Yüksek öncelikli kuyrukta görev zamanla
at -q a 14:00
# Düşük öncelikli kuyrukta çalıştır
at -q e 14:00
# batch modunda çalıştır (sistem yükü düşünce çalışır)
at -q b now
-q kuyruk_harfi: Görevi hangi öncelik kuyruğuna alacağını belirtir. Küçük harfler normal at görevleri, büyük harfler batch görevleri içindir. Varsayılan kuyruk a harfidir.
Gerçek Dünya Senaryoları
Senaryo 1: Gece Yarısı Veritabanı Yedeklemesi
Pratikte en sık kullandığım senaryolardan biri. MySQL/MariaDB veritabanının iş saatleri dışında yedeklenmesi:
# Yedekleme scriptini hazırla
cat << 'EOF' > /tmp/db_backup.sh
#!/bin/bash
TARIH=$(date +%Y%m%d_%H%M%S)
YEDEK_DIZIN="/backup/mysql"
mkdir -p "$YEDEK_DIZIN"
# Veritabanını yedekle
mysqldump -u root -p'sifre' --all-databases | gzip > "$YEDEK_DIZIN/full_backup_$TARIH.sql.gz"
# 7 günden eski yedekleri temizle
find "$YEDEK_DIZIN" -name "*.sql.gz" -mtime +7 -delete
# Bildirim gönder
echo "Veritabani yedegi tamamlandi: full_backup_$TARIH.sql.gz" | mail -s "Yedekleme Raporu" [email protected]
EOF
chmod +x /tmp/db_backup.sh
# Görev zamanla
at 02:30 tomorrow < /tmp/db_backup.sh
Senaryo 2: Bakım Penceresinde Servis Yeniden Başlatma
Uygulama sunucusunda bir sorun var, bir türlü tam düzelmiyor. Gece bakım penceresinde yeniden başlatmak gerekiyor:
# Systemd servisini gece 01:00'de yeniden başlat
at 01:00
at> systemctl restart uygulama-servisi
at> systemctl restart nginx
at> logger "Bakim penceresi: Servisler yeniden baslatildi"
at> <EOT>
logger komutuyla syslog’a kayıt düşmek iyi bir alışkanlık. Sabah kalkıp ne olduğunu merak ettiğinizde journalctl ile kontrol edebilirsiniz.
Senaryo 3: Geçici Güvenlik Duvarı Kuralı
Bir geliştiriciyle uzaktan çalışıyorsunuz, geçici olarak bir port açmanız gerekiyor ama unutup kapatmamak istemiyorsunuz:
# Şu an 8080 portunu aç
iptables -A INPUT -p tcp --dport 8080 -j ACCEPT
echo "Port 8080 acildi: $(date)"
# 2 saat sonra otomatik kapat
at now + 2 hours
at> iptables -D INPUT -p tcp --dport 8080 -j ACCEPT
at> logger "Port 8080 otomatik kapatildi"
at> <EOT>
Bu yaklaşım güvenlik açısından altın değerinde. Geçici erişimler her zaman zamanla sınırlandırılmalı.
Senaryo 4: Log Arşivleme
Disk dolmadan logları arşivlemek için haftalık bir defaya mahsus işlem:
# Log arşivleme scriptini at ile zamanla
cat << 'EOF' > /tmp/log_arsiv.sh
#!/bin/bash
TARIH=$(date +%Y%m)
LOG_DIZIN="/var/log/uygulama"
ARSIV_DIZIN="/archive/logs"
mkdir -p "$ARSIV_DIZIN"
tar -czf "$ARSIV_DIZIN/logs_$TARIH.tar.gz" "$LOG_DIZIN"/*.log
# Orijinal logları temizle
> "$LOG_DIZIN/uygulama.log"
> "$LOG_DIZIN/hata.log"
echo "Log arsivleme tamamlandi: logs_$TARIH.tar.gz" | mail -s "Log Arsiv" [email protected]
EOF
at 04:00 Jul 31 < /tmp/log_arsiv.sh
Çıktı ve E-posta Bildirimleri
at görevlerinin çıktısı varsayılan olarak yerel e-posta sistemine gönderilir. Sunucunuzda mail servisi kuruluysa görev tamamlandığında çıktıyı mail olarak alırsınız. Bu davranışı kontrol etmek için birkaç yöntem var:
# Çıktıyı dosyaya yönlendir, mail gönderme
at 23:00
at> /usr/local/bin/backup.sh > /var/log/backup_output.log 2>&1
at> <EOT>
# Hem dosyaya yaz hem de mail gönder
at 23:00
at> /usr/local/bin/backup.sh 2>&1 | tee /var/log/backup.log | mail -s "Yedekleme Sonucu" [email protected]
at> <EOT>
-M parametresi: Çıktı olsa bile mail göndermez. -m parametresi: Hiç çıktı olmasa bile tamamlandı bildirimi gönderir.
# Mail bildirimi olmadan çalıştır
at -M 03:00 < /tmp/bakim.sh
# Her durumda mail bildir
at -m 03:00 < /tmp/bakim.sh
Erişim Kontrolü: /etc/at.allow ve /etc/at.deny
Sistem yöneticisi olarak hangi kullanıcıların at kullanabileceğini kontrol edebilirsiniz:
# at.allow dosyası - sadece buradaki kullanıcılar kullanabilir
cat /etc/at.allow
# at.deny dosyası - buradaki kullanıcılar KULLANAMAZ
cat /etc/at.deny
# Belirli bir kullanıcıyı at kullanımından engelle
echo "guvenilmezkullanici" >> /etc/at.deny
# Sadece yetkili kullanıcılara izin ver
echo "otomasyon" > /etc/at.allow
echo "root" >> /etc/at.allow
Kural şu şekilde işler:
/etc/at.allowvarsa sadece bu dosyadaki kullanıcılaratkullanabilir./etc/at.allowyoksa,/etc/at.denyiçindeki kullanıcılar hariç herkes kullanabilir.- Her iki dosya da yoksa genellikle sadece root kullanabilir (dağıtıma göre değişir).
at ile Shell Script Entegrasyonu
Daha karmaşık otomasyon senaryolarında at komutunu shell scriptleri içinde de kullanabilirsiniz. Bu özellikle “kendi kendini zamanlayan” görevler için ilginç bir yaklaşım:
#!/bin/bash
# kendi_kendine_zamanla.sh
# Bu script tamamlandıktan 6 saat sonra kendini tekrar çalıştırır
SCRIPT_YOLU="$(readlink -f "$0")"
LOG="/var/log/periyodik_kontrol.log"
echo "$(date): Kontrol basliyor..." >> "$LOG"
# Asıl işlem burada
df -h | grep -E '^/dev' | awk '{if($5+0 > 80) print "UYARI: "$6" disk doluluk orani: "$5}' >> "$LOG"
# 6 saat sonra kendini tekrar zamanla
echo "$SCRIPT_YOLU" | at now + 6 hours
echo "$(date): Kontrol tamamlandi, sonraki calisma 6 saat sonra." >> "$LOG"
Bu yaklaşım cron’a alternatif bir yöntem olsa da dikkatli kullanılmalı. Görev bir şekilde başarısız olursa döngü kırılır ve bir sonraki çalışma olmaz. Bu hem avantaj hem dezavantaj. Kritik görevler için cron daha güvenilir.
Sorun Giderme
Pratik hayatta at ile ilgili en sık karşılaşılan sorunlar şunlar:
Görev Çalışmıyor:
# atd servisinin durumunu kontrol et
systemctl status atd
# Sistem loglarında at ile ilgili hatalara bak
journalctl -u atd --since today
# Görev var mı kontrol et
atq
Çevre Değişkenleri Sorunu:
at görevleri, komutu oluşturduğunuz anın çevre değişkenlerini alır. Ancak PATH gibi değişkenler bazen sorun çıkarır. Güvenli yaklaşım tam yolları kullanmak:
at 03:00
at> export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
at> /usr/local/bin/backup.sh
at> <EOT>
Zaman Dilimi Karışıklığı:
Sunucu saatinin doğru ayarlandığından emin olun:
# Sistem saatini kontrol et
date
timedatectl
# Saat dilimini ayarla
timedatectl set-timezone Europe/Istanbul
at ve batch Komutu Farkı
batch komutu at‘in kardeşidir. Görev çalışma zamanı belirtmek yerine sistem yükünün belirli bir eşiğin altına düştüğünde görevi çalıştırır:
# Sistem yükü 1.5'in altına düşünce çalıştır
batch < /tmp/yogun_islem.sh
# Veya
at -q b now < /tmp/yogun_islem.sh
batch, yoğun CPU gerektiren işlemler için iş saatlerinde bile kullanılabilir. Sistem boşta kalınca görevi çalıştırır.
Güvenlik Notları
at komutu kullanırken aklınızın bir köşesinde tutmanız gereken birkaç güvenlik noktası var:
- Script dosyaları yalnızca yetkili kullanıcılar tarafından yazılabilir olmalı. Başkasının script dosyanızı değiştirip zararlı komutlar ekleyebileceğini unutmayın.
- Hassas bilgileri (şifreler, token’lar) doğrudan
atgörevlerine yazmaktan kaçının. Bunları güvenli konfigürasyon dosyalarından okuyun. - Görev içeriğini
at -cile düzenli aralıklarla kontrol edin, özellikle paylaşılan sistemlerde. - Root olarak çalışan
atgörevlerini minimize edin, mümkünse yetkisiz kullanıcılarla çalıştırın.
Sonuç
at komutu, sistem yöneticilerinin araç kutusunda hakkını yeterince almayan ama gerçekten işlevsel bir araç. Cron’un gölgesinde kalmış olsa da, tek seferlik zamanlanmış görevler söz konusu olduğunda at çok daha temiz ve pratik bir çözüm sunuyor. “Bir kere çalışsın, bitsin” mantığıyla yaklaşılan her senaryoda, gereksiz bir cron entry’si açmak yerine at kullanmayı düşünün.
Gece yarısı bakım işlemleri, tek seferlik veri migrasyonları, geçici erişim kontrolü, çalışma saatleri dışında servis yeniden başlatmaları… Bunların hepsi at ile zarifçe çözülebilecek durumlar. Servis kontrolünü unutmayın, çevre değişkenlerine dikkat edin, çıktıları mutlaka log dosyalarına yönlendirin ve işiniz bittiğinde atq ile görevin gerçekten planlandığını doğrulayın.
Sysadmin hayatının güzelliği tam olarak bu tür küçük ama etkili araçları doğru zamanda kullanmaktan geçiyor.