Cron görevi neden çalışmıyor? 5 yaygın hata
Cron görevinin çalışmama nedenlerini inceleyin. PATH eksikliği, kaçış karakteri almamış yüzde işareti, yanlış crontab dosyası veya kaybolan çıktı gibi 5 temel sorunu çözün.
Cron göreviniz neden çalışmıyor
"Asla çalışmayan" bir cron görevi neredeyse her zaman çalışmıştır. Görev, sizin shell ortamınızdan farklı bir ortamda çalışmış, ilk saniyede başarısız olmuş ve hata mesajı okumadığınız bir yere gitmiştir. Beş temel neden hemen hemen her sorunu açıklar: arama yolu (search path), yüzde işareti, yanlış crontab dosyası, e-postaya giden çıktı ve oturum açma gerektiren bir betik.
cron, crontab dosyalarını okuyan ve komutları bir zaman çizelgesine göre başlatan bir daemon'dır (arka plan servisi). Sizin .bashrc dosyanızı okumaz, terminal açmaz, login shell başlatmaz ve bir komut başarısız olduğunda size bildirim göndermez. Aşağıdaki her neden, bu dört temel gerçeğe dayanır.
Bunları sırasıyla inceleyin ve hepsinin altındaki şu soruyla başlayın: cron gerçekten tetiklendi mi? "cron görevi hiç başlatmadı" ve "görev başladı ve kapandı" ifadeleri, hiçbir ortak noktası olmayan farklı sorunlardır; bu yüzden önce bu soruyu yanıtlayın.
Cron tetiklendi mi?
Daemon, farklı dağıtım ailelerinde farklı bir birim ismine sahiptir. Her ikisini de kontrol edin ve ardından günlük kayıtlarını okuyun.
systemctl status cron
systemctl status crond
journalctl -u cron --since "2 hours ago"
journalctl -u crond --since "2 hours ago"Debian ve Ubuntu sistemlerinde birim ismi cron olarak geçer. Fedora, Rocky ve Alma sistemlerinde ise crond olarak adlandırılır. Belirli bir makinede bu isimlerden yalnızca biri mevcuttur; dolayısıyla komutlardan birinin bilinmeyen birim hatası vermesi normaldir ve bir arıza teşkil etmez.
Kendi sisteminizin oluşturduğu kayıtları okuyun. Bir rehberden kopyalanmış satırları aramayın, çünkü ifade biçimi cron uygulamaları ve günlük yapılandırmaları arasında farklılık gösterir. Yalnızca iki şeyi kontrol ediyorsunuz: zamanlamanızda belirttiğiniz dakikaya ait bir kayıt var mı ve bu kayıt komutunuzu içeriyor mu? Komutunuzu içeren bir kayıt, cron'un görevini yaptığını ve hatanın komutun içinde olduğunu gösterir. Hiç kayıt olmaması, cron'un zamanlamanızı hiç almadığı anlamına gelir; bu da aşağıdaki 3. nedendir.
Bazı imajlar, cron mesajlarını journal yerine rsyslog aracılığıyla bir dosyaya gönderir. /var/log dizininde cron veya syslog adında bir dosya olup olmadığını kontrol edin ve dosyanın son kısmını okuyun.
ls -l /var/log
sudo tail -n 50 /var/log/syslogEğer ne birim ne de günlük dosyası mevcutsa, cron yüklü olmayabilir. Minimal bulut imajları ve container yapıları genellikle cron içermez.
dpkg -l cron
rpm -q cronie
sudo apt install cron
sudo dnf install cronie
sudo systemctl enable --now cronNeden 1: cron PATH değişkeninize sahip değildir
Etkileşimli kabuğunuz PATH dosyasını /etc/profile, ~/.profile, ~/.bashrc ve bu dosyaların kaynak gösterdiği her şeyden oluşturur. Bunların hiçbiri bir cron işi için çalıştırılmaz. cron, komutu kendi kısıtlı ortamıyla başlatır; bu nedenle standart sistem dizinlerinin dışında kalan bir program bulunamaz. /usr/local/bin, /opt altındaki her şey, bir dil sürüm yöneticisi, bir Python sanal ortamı veya bir Go çalışma alanı bu duruma adaydır. İş ilk satırında başarısız olur ve kabuk, tam ifadesi hangi kabuğun çalıştırdığına bağlı olan "bulunamadı" türünde bir hata yazar.
İşinizin kullandığı her komutun gerçek yolunu bulun.
command -v docker
command -v node
readlink -f "$(command -v node)"Ardından ya bu mutlak yolları işin içine yazın ya da crontab dosyasının en üstünde bir kez PATH değişkenini ayarlayın.
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
0 3 * * * /usr/local/bin/mytool runKendi makinenizdeki listeyi echo "$PATH" ile alın ve yalnızca etkileşimli bir oturum içinde var olan her şeyi çıkarın. Burada tek bir kural önemlidir: cron, bu atama satırlarındaki değişkenleri genişletmez. PATH=$PATH:/usr/local/bin, $PATH:/usr/local/bin metnini olduğu gibi saklar; bu nedenle iş, hiçbir kullanılabilir dizin içermeyen bir arama yoluyla sonuçlanır. Listenin tamamını açıkça yazın.
Bir sürüm yöneticisi, bir yoldan daha fazlasına ihtiyaç duyar. nvm, pyenv, rbenv ve asdf, .bashrc dosyanızdan bir kabuk işlevi veya bir shims dizini yükler ve bir cron işi bu dosyayı asla okumaz. Sürümlü ikili dosyayı mutlak yol ile çağırın veya yöneticinin başlatma betiğini kendi betiğinizin ilk satırı olarak kaynak gösterin (source).
Neden 2: yüzde işareti komutunuzu sonlandırır
Bir crontab dosyasının komut alanında % sıradan bir karakter değildir. Kaçış karakteri kullanılmamış ilk % komutu sonlandırır. Bu işaretten sonra gelen her şey, komuta standart girdi (stdin) olarak iletilir ve sonraki her % bir satır başı karakterine dönüşür. Bu, bir programa kısa girdiler sağlamak için kullanılan gerçek bir cron özelliğidir; tarih damgalı dosya adlarının klasik bozuk crontab girdisi olmasının nedeni de budur.
0 3 * * * /usr/bin/tar -czf /srv/backups/site-$(date +%F).tar.gz /srv/site yazdığınızda tar hiçbir zaman biçimlendirilmiş bir tarih görmez. cron satırı ilk % işaretinde keser, bu nedenle kabuk (shell) tamamlanmamış bir komut yerleştirmesi alır ve satırınızın geri kalanı standart girdi olarak ulaşır. Her yüzde işaretini bir ters eğik çizgi ile kaçış karakterine dönüştürün.
0 3 * * * /usr/bin/tar -czf /srv/backups/site-$(date +\%F).tar.gz /srv/siteİki katman, o tek satırı sırayla okur. \% bir cron kuralıdır ve cron herhangi bir şeyi başlatmadan önce uygulanır. $(date +\%F) ise komut yerleştirmesi (command substitution) işlemidir ve cron tarafından başlatılan kabuk tarafından daha sonra uygulanır. Hangi karakterin hangi katmana ait olduğunu bilmek, işin tüm püf noktasıdır.
Daha güvenli alışkanlık, mantığı tamamen crontab dosyasının dışında tutmaktır. Mantığı, yüzde işaretinin özel bir anlam taşımadığı bir betik (script) dosyasına yerleştirin.
#!/bin/bash
set -euo pipefail
stamp="$(date +%F)"
tar -czf "/srv/backups/site-${stamp}.tar.gz" /srv/siteBöylece crontab satırı yalnızca bir yol, bir yönlendirme ve başka hiçbir şey içermez. Bir bakışta okuyabildiğiniz bir crontab, hata ayıklayabildiğiniz bir crontab'dır.
Neden 3: Hangi crontab dosyasını düzenlediniz?
Tek bir crontab dosyası yoktur. Farklı sahipleri ve farklı alan sayıları olan birden fazla dosya bulunur; yanlış dosyaya yazılan bir iş görünmez olur.
crontab -ekomutu çalıştıran kullanıcının crontab dosyasını düzenler.sudo crontab -eise root kullanıcısınınkini düzenler. Aynı sunucuda hata ayıklayan iki kişi genellikle iki farklı dosyayı okumaktadır.sudo crontab -l -u deploybaşka bir kullanıcının crontab dosyasını listeler; işi çalıştırması gereken hesap için nelerin yüklü olduğunu doğrulamanın yolu budur./etc/crontabve/etc/cron.diçindeki her dosya, zamanlama ile komut arasında fazladan bir alan taşır: komutu çalıştıracak kullanıcı. Beş alanlı bir kullanıcı crontab satırını/etc/cron.diçine yapıştırırsanız, komutunuzun ilk kelimesi kullanıcı adı olarak okunur./etc/cron.diçindeki dosyalar harfler, rakamlar, alt çizgiler ve tire işaretleri ile adlandırılmalıdır.backup.shveyasite.confgibi bir dosya, sadece ismi nedeniyle atlanır. Dosyayıbackupolarak yeniden adlandırın ve log kayıtlarınızı tekrar kontrol edin./etc/cron.diçindeki dosyaların sahibi root olmalı ve grup ya da diğer kullanıcılar tarafından yazılabilir olmamalıdır.ls -l /etc/cron.dsize her iki durumu da aynı anda gösterir./etc/cron.dailyve benzeri dizinlere bırakılan betikler aynı adlandırma kuralına tabidir ve ayrıca çalıştırılabilir (execute) bitine sahip olmalıdır. Çalıştırılabilir bitinin eksik olması, işlemin sessizce atlanmasına neden olur./etc/cron.allowve/etc/cron.denydosyaları, kimin crontab yükleyebileceğine karar verir. Eğer sunucunuzda bunlardan biri varsa, kullanıcınızın crontab kullanma yetkisi olduğunu varsaymadan önce bu dosyaları okuyun.
Spool dosyasını elle düzenlemek yerine crontab komutu ile kullanıcı crontab dosyasını yükleyin; çünkü crontab dosyayı yüklemeden önce ayrıştırır. Kaydettiğinizde, komutun size ne döndürdüğünü okuyun. Eğer dosyayı reddederse, önceki sürüm aktif kalır ve yaptığınız değişiklik asla devreye girmez; bu durum cron sizi görmezden geliyormuş gibi görünür.
Sahip bilgisi izinleri de belirler. root crontab dosyasındaki bir iş, uygulamaların okuyamayabileceği root sahipli dosyalar oluşturur. Normal bir kullanıcı crontab dosyasındaki bir iş ise sadece root tarafından erişilebilen bir dizini okuyamaz. Sahibi yapılan işe göre belirleyin: uygulama bakımı, uygulamanın kendi hesabına aittir; WordPress wp-cron yerine sistem cron işi kullanmanın arkasındaki mantık budur. İşinizin oluşturduğu dosyaların modu, devraldığı umask değerinden gelir ve bu değer shell'inizinkinden farklıdır; bu nedenle iş çıktısı okunamaz halde geliyorsa umask dosya izinlerini nasıl ayarlar konusunu okumakta fayda vardır.
Neden 4: Çıktı kimsenin okumadığı bir e-postaya gitti
cron, bir işin standart çıktıya ve standart hataya yazdığı her şeyi toplar. İş herhangi bir metin yazdıysa, cron bu metni yerel posta sistemine, crontab sahibine veya MAILTO içinde belirtilen adrese gönderir. Kısıtlı bir VPS üzerinde genellikle bir MTA (posta aktarım aracısı) yüklü değildir, bu nedenle hiçbir şey teslim edilmez. Hatanız bir anlığına oluştu ve ardından kayboldu. Hatalı bir işin sessiz görünmesinin tek nedeni budur.
Bunun yerine çıktıyı kontrol ettiğiniz bir dosyaya yönlendirin.
0 3 * * * /usr/local/sbin/backup-site.sh >> /var/log/backup-site.log 2>&1>>, standart çıktıyı dosyaya ekler. 2>&1, standart hatayı o an standart çıktının işaret ettiği yere yönlendirir, bu nedenle bu ifade yönlendirmeden sonra gelmelidir. 2>&1 >> file şeklinde ters yazıldığında, standart hata orijinal hedefini korur ve aradığınız hata dosyaya asla ulaşmayan kısım olur.
Journal, bir diğer iyi hedeftir. logger, seçtiğiniz bir etiket altında syslog içine yazar.
0 3 * * * /usr/local/sbin/backup-site.sh 2>&1 | logger -t backup-siteBunu journalctl -t backup-site ile geri okuyun. Bu, işin kendi çıktısını cron girdilerinin yanında tutar, böylece zaman çizelgesini takip etmek kolaylaşır. Ayrıca sunucuda hangi kullanıcının hangi komutu çalıştırdığına dair bir kayda ihtiyacınız varsa, bu ayrı bir sistemdir ve sunucunuzdaki kullanıcı komutlarını denetleme konusu bunu kapsar.
Bir crontab'ın en üstündeki MAILTO="", altındaki işler için e-posta gönderimini kapatır. MAILTO değerini gerçek bir adrese ayarlamak yalnızca çalışan bir MTA varsa işe yarar, bu nedenle ona güvenmeden önce e-postanın sunucudan çıktığını doğrulayın.
Hata ayıklama sırasında tek bir kural: asla > /dev/null 2>&1 eklemeyin. Bu, her crontab'daki en popüler satırdır ve elinizdeki tek kanıtı yok eder. İş çalışır hale geldiğinde, isterseniz bunu daha sonra geri ekleyin.
Neden 5: Betik, cron'un sağlamadığı bir ortamı varsayıyor
Komut bulunduğunda ve çıktısı yakalandığında, geriye oturumunuzun size ücretsiz olarak sunduğu diğer her şey kalır.
- Kabuk (shell) bash olmayabilir.
ls -l /bin/shile kontrol edin. Debian ve Ubuntu üzerinde bu, dash'e işaret eder; bu nedenle çift köşeli parantez testi, diziler vesourcesözdizimi hatasıyla başarısız olur. Betiğe bir#!/bin/bashsatırı ekleyin ve betiği bu şekilde çağırın ya da crontab'ın en üstüneSHELLayarını ekleyin. - Çalışma dizini, içinde bulunduğunuz dizin değildir. Her yerde mutlak yollar kullanın veya betiğin ilk satırında ilgili dizine
cdyapın. Göreceli yol kullanımı, bir işin "elle çalıştırdığımda çalışıyor" demesinin en yaygın tek nedenidir. - Yerel ayarlar (locale) oturumunuzunkilerle aynı değildir. Tarih veya sayı biçimlendiren ya da metin sıralayan her şey, farklı bir
LANGaltında farklı çıktılar üretebilir. Eğer sonraki bir adım bu çıktıyı ayrıştırıyorsa, şansa bırakmak yerine yerel ayarları betik içinde tanımlayın. - TTY (terminal) yoktur. Onay isteyen, düzenleyici açan veya ilerleme çubuğu çizen bir komut askıda kalabilir veya sonlanabilir. Aracın sunduğu etkileşimli olmayan (non-interactive) bayrağı ekleyin.
- SSH aracısı (agent) yoktur.
SSH_AUTH_SOCK, cron'un ortamında bulunmaz; bu nedenle aracınız yüklü olduğu için çalışan birsshveyarsynckomutu, kimlik doğrulaması yapamadığı için başarısız olur. İşe, işi çalıştıran kullanıcıya ait özel bir anahtar tanımlayın. - Kullanıcı oturum veri yolu (session bus) yoktur, bu nedenle cron işinden gelen
systemctl --user,XDG_RUNTIME_DIRayarlanana kadar başarısız olur. Bir systemd birimi (unit) daha iyi bir çözümdür.
Fedora, Rocky ve Alma üzerinde bir şüpheli daha vardır. SELinux, cron işlerini kısıtlar; bu nedenle beklenmedik bir etikete sahip bir yola erişen iş, dosya izinleri doğru görünse bile reddedilir. sudo ausearch -m avc -ts recent ile reddedilen işlemleri kontrol edin ve herhangi bir şeyi kapatmadan önce Sunucular için SELinux temelleri belgesini okuyun.
Cron ortamını gösteren bir dakikalık inceleme
Cron ortamında nelerin tanımlı olduğunu tahmin etmeyi bırakın ve doğrudan okuyun. Her şeyi bir dosyaya yazdıran bir betik oluşturun, bunu her dakika çalışacak şekilde zamanlayın, bekleyin ve ardından dosyayı okuyun.
cat > /home/deploy/cron-probe.sh <<'EOF'
#!/bin/bash
echo "=== probe ==="
date -Is
pwd
id
echo "SHELL=$SHELL"
echo "LANG=$LANG"
command -v node || echo "node is not on this PATH"
env | sort
EOF
chmod +x /home/deploy/cron-probe.shGerçek işin çalıştırıldığı kullanıcının crontab dosyasına, her iki tarafta da mutlak yollar (absolute paths) kullanarak bir satır ekleyin.
* * * * * /home/deploy/cron-probe.sh >> /home/deploy/cron-probe.log 2>&1Bir dakika bekleyin, ardından /home/deploy/cron-probe.log dosyasını okuyun ve kendi kabuğunuzda (shell) çalıştırdığınız aynı komutlarla karşılaştırın. PATH satırı, çalışma dizini ve yerel ayarlar (locale) genellikle hatanın nedenini tek başlarına açıklar. Kurulumla ilgili iki detaya dikkat edin: yüzde işaretleri betiğin içinde yer alır, dolayısıyla cron'un kuralı burada geçerli değildir ve günlük dosyası yolu, işi çalıştıran kullanıcının yazma iznine sahip olduğu bir dizindedir.
Cevabınızı aldığınız anda bu crontab satırını silin. Her dakika çalışan ve bir dosyaya ekleme yapan bir iş, küçük bir diski hızla dolduracaktır ve bunu sessizce yapacaktır.
Planladığınız zamanlama doğru mu?
Kullanıcı crontab satırı beş alandan oluşur: dakika, saat, ayın günü, ay ve haftanın günü. Bunlardan ikisi, kullanıcıları şaşırtan bir şekilde etkileşime girer.
Ayın günü ve haftanın günü kısıtlandığında, yani ikisi de * olmadığında, cron işi her iki alandan biri eşleştiğinde çalıştırır. 0 0 13 * 5 ifadesi "ayın 13'üne denk gelen Cuma" anlamına gelmez. Bu komut, her ayın 13'ünde gece yarısı ve her Cuma gece yarısı çalışır. Belirli bir günü hedeflemek için bu iki alandan birini * olarak bırakın ve diğerini betik içerisinde test edin.
cron, sistem saat dilimini kullanır. Birçok VPS imajı varsayılan olarak UTC (Eşgüdümlü Evrensel Zaman) ayarıyla gelir; bu nedenle 03:00 için planladığınız bir iş, öğleden sonranıza denk gelebilecek şekilde 03:00 UTC'de çalışır. timedatectl komutu, sunucunuzun o an hangi saat dilimini kullandığını gösterir. Kendi bilgisayarınızla aynı olduğunu varsaymak yerine sunucunuzdaki ayarı kontrol edin.
Zamanlama ile ilgili iki tuzak daha bilinmelidir. @reboot, cron başladığı anda tetiklenir; bu an ağın hazır olduğu anla aynı değildir. Bu nedenle DNS veya uzak bir sunucuya ihtiyaç duyan bir iş, önyükleme sırasında başarısız olabilir ancak daha sonra manuel olarak çalıştırıldığında başarılı olabilir. Ayrıca, yavaş çalışan bir işin, önceki kopyası hala devam ederken tekrar başlamasını engelleyen bir mekanizma yoktur. İşi bir kilit (lock) mekanizması ile sarmalayın.
*/5 * * * * /usr/bin/flock -n /tmp/backup-site.lock /usr/local/sbin/backup-site.sh >> /var/log/backup-site.log 2>&1flock -n, kilit zaten tutuluyorsa hemen pes eder; böylece çakışan çalışma, ilkinin üzerine binmek yerine durdurulur.
systemd timer ne zaman daha iyi bir araçtır
cron tek bir konuda iyidir: bu komutu şu zamanda çalıştır. Diğer tüm konularda zayıftır. Bir timer, herhangi bir yönlendirme yapmadan journal kaydına erişmenizi, daha sonra sorgulayabileceğiniz bir çıkış durumuna, network-online.target ile sıralama yapabilmenize ve yüzlerce sunucunun aynı saniyede başlamasını engelleyen rastgele bir gecikme süresine sahip olmanızı sağlar. İşiniz bunlardan herhangi birine ihtiyaç duyduğunda, bir VPS üzerinde systemd servisi ve timer kullanmak, bir crontab satırını yönetmekten daha az iş yükü getirir. Yeniden deneme davranışı da buraya aittir; çünkü systemd yeniden başlatma politikaları bir hata sonrasında ne olacağına karar verir ve cron'un bu soruya hiçbir yanıtı yoktur.
Küçük işler için cron'u tutun. Bağımlılıkları olan veya yeniden deneme politikası gerektiren her şeyi bir timer'a taşıyın. Her ikisi de aynı sunucuda çalışabilir, bu nedenle tek seferde bitirmeniz gereken bir taşıma işlemi değildir.
FAQ
Cron işim manuel çalıştırıldığında neden cron üzerinden başarısız oluyor?
Çünkü sizin kabuk ortamınız ile cron ortamı birbirinden farklıdır. Oturum açtığınız kabuk, /etc/profile ve ~/.bashrc dosyalarını okuyarak PATH değişkenini, yerel ayarları ve aracı değişkenlerini yapılandırır. cron ise komutu bunların hiçbiri olmadan, farklı bir çalışma dizininden ve bazen farklı bir kabuk kullanarak başlatır. Her komut için mutlak yolları kullanın, ihtiyaç duyduğunuz değişkenleri crontab dosyasının en üstünde veya betiğin içinde tanımlayın. Ayrıca cron'un gerçek ortamını tahmin etmek yerine görmek için, env | sort, pwd ve id komutlarını bir log dosyasına yazdıran bir dakikalık bir test işi planlayın.
Cron'un işimi gerçekten çalıştırıp çalıştırmadığını nasıl kontrol ederim?
Daemon'un log kayıtlarını okuyun. Debian ve Ubuntu sistemlerde journalctl -u cron, Fedora, Rocky ve Alma sistemlerde ise journalctl -u crond komutunu kullanın; bazı imajlar mesajları rsyslog aracılığıyla /var/log altındaki bir dosyaya yönlendirir. Zamanladığınız dakikaya ait bir kayıt olup olmadığını ve komutunuzun adının geçip geçmediğini kontrol edin. Kayıt yoksa cron zamanlamayı hiç almamış demektir; bu durumda doğru crontab dosyasını düzenlediğinizden emin olun. Kayıt var ancak sonuç yoksa komut başlamış ve sonlanmış demektir; bu durumda çıktıyı bir yönlendirme ile yakalayın.
date +%Y neden crontab içinde hata veriyor?
cron, komut satırındaki % karakterini özel bir karakter olarak değerlendirir. Kaçış karakteri kullanılmamış ilk % komutu sonlandırır, sonrasındaki her şey standart girdi olarak komuta iletilir ve her % karakteri yeni bir satıra dönüşür. Bu nedenle tarih formatlı bir dosya adı, yazdığınız programa asla ulaşamaz. Her yüzde işaretini \% şeklinde kaçırın veya komutu bir betik dosyasına taşıyıp cron üzerinden bu betiği çağırın; çünkü betik dosyası içinde yüzde işaretinin özel bir anlamı yoktur.
Cron işimin çıktısı nereye gidiyor?
Yerel posta sistemine, crontab sahibine veya MAILTO değişkeninde tanımlanan adrese gönderilir. Çoğu VPS imajında bir posta aktarım aracısı (MTA) yüklü değildir, bu nedenle mesajlar kaybolur ve iş sessizce çalışmış gibi görünür. Çıktıyı >> /path/to/log 2>&1 ile bir dosyaya yönlendirin (standart hatanın standart çıktıya dahil edilmesi için bu sıralamayı koruyun) veya logger -t myjob üzerinden borulayıp journalctl -t myjob ile okuyun. Hata ayıklama sürecinde > /dev/null 2>&1 kullanmaktan kaçının.
Cron mu yoksa systemd timer mı kullanmalıyım?
Sabit bir zamanda çalışan basit komutlar için, özellikle systemd çalıştırmayan bir makineye taşıma ihtimaliniz varsa cron kullanın. Çıktıların yönlendirme yapmadan journal üzerinde görünmesini, sorgulanabilir bir çıkış durumu, ağ bağlantısı sağlandıktan sonra çalışma, rastgele başlatma gecikmesi veya hata sonrası yeniden deneme politikası gibi özellikler istiyorsanız timer kullanın. Her ikisi de aynı sunucuda çalışabilir; bu sayede işleri ihtiyaç duydukça aşamalı olarak taşıyabilirsiniz.